From 3ebe9ab5e7bb71e3dfc87bc556f3b0c37d4fb83a Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 2 Jun 2019 19:59:49 +0100 Subject: [PATCH] rustc: use lowering helpers This commit changes the lowering to stop creating HIR statements, expressions and patterns directly and instead uses the pre-existing helper functions. --- src/librustc/hir/lowering.rs | 83 ++++++++++++------------------------ 1 file changed, 28 insertions(+), 55 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d6d8b60f21f27..e9a86f708eff2 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3039,12 +3039,15 @@ impl<'a> LoweringContext<'a> { // Async function arguments are lowered into the closure body so that they are // captured and so that the drop order matches the equivalent non-async functions. // + // from: + // // async fn foo(: , : , : ) { // async move { // } // } // - // // ...becomes... + // into: + // // fn foo(__arg0: , __arg1: , __arg2: ) { // async move { // let __arg2 = __arg2; @@ -3076,61 +3079,29 @@ impl<'a> LoweringContext<'a> { }, }; + let desugared_span = + this.mark_span_with_reason(CompilerDesugaringKind::Async, span, None); + // Construct an argument representing `__argN: ` to replace the argument of the // async function. // // If this is the simple case, this argument will end up being the same as the // original argument, but with a different pattern id. - let new_argument_id = this.next_id(); - let desugared_span = - this.mark_span_with_reason(CompilerDesugaringKind::Async, span, None); + let (new_argument_pat, new_argument_id) = this.pat_ident(desugared_span, ident); let new_argument = hir::Arg { hir_id: argument.hir_id, - pat: P(hir::Pat { - hir_id: new_argument_id, - node: hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, - new_argument_id, ident, None), - span: desugared_span, - }), - source: hir::ArgSource::AsyncFn, - }; - - let construct_stmt = |this: &mut LoweringContext<'_>, pat: P, - init_pat_id: hir::HirId| { - hir::Stmt { - hir_id: this.next_id(), - node: hir::StmtKind::Local(P(hir::Local { - pat, - // We explicitly do not specify the type for any statements. When the - // user's argument type is `impl Trait` then this would require the - // `impl_trait_in_bindings` feature to also be present for that same - // type to be valid in this binding. At the time of writing (13 Mar 19), - // `impl_trait_in_bindings` is not stable. - ty: None, - init: Some(P(hir::Expr { - span, - node: hir::ExprKind::Path(hir::QPath::Resolved(None, P(hir::Path { - span, - res: Res::Local(init_pat_id), - segments: hir_vec![ hir::PathSegment::from_ident(ident) ], - }))), - attrs: ThinVec::new(), - hir_id: this.next_id(), - })), - hir_id: this.next_id(), - span: desugared_span, - attrs: ThinVec::new(), - source: hir::LocalSource::AsyncFn, - })), - span: desugared_span, - } + pat: new_argument_pat, + source: hir::ArgSource::AsyncFn }; let new_statements = if is_simple_argument { // If this is the simple case, then we only insert one statement that is // `let = ;`. We re-use the original argument's pattern so that // `HirId`s are densely assigned. - (construct_stmt(this, argument.pat, new_argument_id), None) + let expr = this.expr_ident(desugared_span, ident, new_argument_id); + let stmt = this.stmt_let_pat( + desugared_span, Some(P(expr)), argument.pat, hir::LocalSource::AsyncFn); + (stmt, None) } else { // If this is not the simple case, then we construct two statements: // @@ -3147,21 +3118,19 @@ impl<'a> LoweringContext<'a> { // Construct the `let mut __argN = __argN;` statement. It must be a mut binding // because the user may have specified a `ref mut` binding in the next // statement. - let hir_id = this.next_id(); - let move_stmt = construct_stmt( - this, - P(hir::Pat { - hir_id, - node: hir::PatKind::Binding(hir::BindingAnnotation::Mutable, - hir_id, ident, None), - span: desugared_span, - }), - new_argument_id, - ); + let (move_pat, move_id) = this.pat_ident_binding_mode( + desugared_span, ident, hir::BindingAnnotation::Mutable); + let move_expr = this.expr_ident(desugared_span, ident, new_argument_id); + let move_stmt = this.stmt_let_pat( + desugared_span, Some(P(move_expr)), move_pat, hir::LocalSource::AsyncFn); // Construct the `let = __argN;` statement. We re-use the original // argument's pattern so that `HirId`s are densely assigned. - let pattern_stmt = construct_stmt(this, argument.pat, hir_id); + let pattern_expr = this.expr_ident(desugared_span, ident, move_id); + let pattern_stmt = this.stmt_let_pat( + desugared_span, Some(P(pattern_expr)), argument.pat, + hir::LocalSource::AsyncFn); + (move_stmt, Some(pattern_stmt)) }; @@ -5251,6 +5220,10 @@ impl<'a> LoweringContext<'a> { } } + fn arg(&mut self, hir_id: hir::HirId, pat: P, source: hir::ArgSource) -> hir::Arg { + hir::Arg { hir_id, pat, source } + } + fn stmt(&mut self, span: Span, node: hir::StmtKind) -> hir::Stmt { hir::Stmt { span, node, hir_id: self.next_id() } }