Skip to content

Commit

Permalink
[WIP] Allow #[project] to be used on if let expressions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Aaron1011 committed Mar 9, 2020
1 parent e15cd8c commit 198b140
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions pin-project-internal/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,33 @@ pub(crate) fn attribute(args: &TokenStream, input: Stmt, mutability: Mutability)
.unwrap_or_else(|e| e.to_compile_error())
}

fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
match &mut stmt {
fn replace_stmt(stmt: &mut Stmt, mutability: Mutability) -> Result<bool> {
match stmt {
Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
Context::new(mutability).replace_expr_match(expr)
Context::new(mutability).replace_expr_match(expr);
return Ok(true)
}
Stmt::Expr(Expr::If(expr_if)) => {
if let Expr::Let(ref mut expr) = &mut *expr_if.cond {
Context::new(mutability).replace_expr_let(expr);
return Ok(true);
}
}
Stmt::Local(local) => Context::new(mutability).replace_local(local)?,
Stmt::Item(Item::Fn(item)) => replace_item_fn(item, mutability)?,
Stmt::Item(Item::Impl(item)) => replace_item_impl(item, mutability),
Stmt::Item(Item::Use(item)) => replace_item_use(item, mutability)?,
_ => {}
}
Ok(false)
}

fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
if !replace_stmt(&mut stmt, mutability)? {
match &mut stmt {
Stmt::Item(Item::Fn(item)) => replace_item_fn(item, mutability)?,
Stmt::Item(Item::Impl(item)) => replace_item_impl(item, mutability),
Stmt::Item(Item::Use(item)) => replace_item_use(item, mutability)?,
_ => {}
}
}

Ok(stmt.into_token_stream())
}
Expand Down Expand Up @@ -73,6 +89,10 @@ impl Context {
Ok(())
}

fn replace_expr_let(&mut self, expr: &mut ExprLet) {
self.replace_pat(&mut expr.pat, true)
}

fn replace_expr_match(&mut self, expr: &mut ExprMatch) {
expr.arms.iter_mut().for_each(|Arm { pat, .. }| self.replace_pat(pat, true))
}
Expand Down Expand Up @@ -195,17 +215,18 @@ impl FnVisitor {
expr.attrs.find_remove(self.name())?
}
Stmt::Local(local) => local.attrs.find_remove(self.name())?,
Stmt::Expr(Expr::If(expr_if)) => {
if let Expr::Let(_) = &*expr_if.cond {
expr_if.attrs.find_remove(self.name())?
} else {
None
}
}
_ => return Ok(()),
};
if let Some(attr) = attr {
parse_as_empty(&attr.tokens)?;
match node {
Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
Context::new(self.mutability).replace_expr_match(expr)
}
Stmt::Local(local) => Context::new(self.mutability).replace_local(local)?,
_ => unreachable!(),
}
replace_stmt(node, self.mutability)?;
}
Ok(())
}
Expand Down

0 comments on commit 198b140

Please sign in to comment.