diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 8000666044a1a..9cf365addca9b 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -262,9 +262,6 @@ pub trait Visitor<'v> : Sized { fn visit_pat(&mut self, p: &'v Pat) { walk_pat(self, p) } - fn visit_argument_source(&mut self, s: &'v ArgSource) { - walk_argument_source(self, s) - } fn visit_anon_const(&mut self, c: &'v AnonConst) { walk_anon_const(self, c) } @@ -402,17 +399,10 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) { for argument in &body.arguments { visitor.visit_id(argument.hir_id); visitor.visit_pat(&argument.pat); - visitor.visit_argument_source(&argument.source); } visitor.visit_expr(&body.value); } -pub fn walk_argument_source<'v, V: Visitor<'v>>(visitor: &mut V, source: &'v ArgSource) { - if let ArgSource::AsyncFn(pat) = source { - visitor.visit_pat(pat); - } -} - pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { // Intentionally visiting the expr first - the initialization expr // dominates the local's definition. diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 08fbd0d20d74d..14a6e93341e32 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -50,6 +50,7 @@ use errors::Applicability; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::thin_vec::ThinVec; +use rustc_data_structures::sync::Lrc; use std::collections::{BTreeSet, BTreeMap}; use std::mem; @@ -58,17 +59,17 @@ use syntax::attr; use syntax::ast; use syntax::ast::*; use syntax::errors; -use syntax::ext::hygiene::Mark; +use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::source_map::{respan, CompilerDesugaringKind, Spanned}; +use syntax::source_map::{self, respan, CompilerDesugaringKind, Spanned}; use syntax::source_map::CompilerDesugaringKind::IfTemporary; use syntax::std_inject; use syntax::symbol::{kw, sym, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::parse::token::Token; use syntax::visit::{self, Visitor}; -use syntax_pos::Span; +use syntax_pos::{edition, Span}; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; @@ -465,32 +466,6 @@ impl<'a> LoweringContext<'a> { visit::walk_pat(self, p) } - fn visit_fn(&mut self, fk: visit::FnKind<'lcx>, fd: &'lcx FnDecl, s: Span, _: NodeId) { - if fk.header().map(|h| h.asyncness.node.is_async()).unwrap_or(false) { - // Don't visit the original pattern for async functions as it will be - // replaced. - for arg in &fd.inputs { - if let ArgSource::AsyncFn(pat) = &arg.source { self.visit_pat(pat); } - self.visit_ty(&arg.ty) - } - self.visit_fn_ret_ty(&fd.output); - - match fk { - visit::FnKind::ItemFn(_, decl, _, body) => { - self.visit_fn_header(decl); - self.visit_block(body) - }, - visit::FnKind::Method(_, sig, _, body) => { - self.visit_fn_header(&sig.header); - self.visit_block(body) - }, - visit::FnKind::Closure(body) => self.visit_expr(body), - } - } else { - visit::walk_fn(self, fk, fd, s) - } - } - fn visit_item(&mut self, item: &'lcx Item) { let hir_id = self.lctx.allocate_hir_id_counter(item.id); @@ -806,7 +781,7 @@ impl<'a> LoweringContext<'a> { }) } - fn record_body(&mut self, value: hir::Expr, arguments: HirVec) -> hir::BodyId { + fn record_body(&mut self, arguments: HirVec, value: hir::Expr) -> hir::BodyId { if self.is_generator && self.is_async_body { span_err!( self.sess, @@ -855,6 +830,27 @@ impl<'a> LoweringContext<'a> { self.sess.diagnostic() } + /// Reuses the span but adds information like the kind of the desugaring and features that are + /// allowed inside this span. + fn mark_span_with_reason( + &self, + reason: CompilerDesugaringKind, + span: Span, + allow_internal_unstable: Option>, + ) -> Span { + let mark = Mark::fresh(Mark::root()); + mark.set_expn_info(source_map::ExpnInfo { + call_site: span, + def_site: Some(span), + format: source_map::CompilerDesugaring(reason), + allow_internal_unstable, + allow_internal_unsafe: false, + local_inner_macros: false, + edition: edition::Edition::from_session(), + }); + span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) + } + fn with_anonymous_lifetime_mode( &mut self, anonymous_lifetime_mode: AnonymousLifetimeMode, @@ -1125,27 +1121,21 @@ impl<'a> LoweringContext<'a> { span: Span, body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr, ) -> hir::ExprKind { - let prev_is_generator = mem::replace(&mut self.is_generator, false); - let prev_is_async_body = mem::replace(&mut self.is_async_body, true); + let capture_clause = self.lower_capture_clause(capture_clause); let output = match ret_ty { Some(ty) => FunctionRetTy::Ty(P(ty.clone())), None => FunctionRetTy::Default(span), }; - let decl = FnDecl { + let ast_decl = FnDecl { inputs: vec![], output, c_variadic: false }; - // Lower the arguments before the body otherwise the body will call `lower_res` expecting - // the argument to have been assigned an id already. - let arguments = self.lower_args(Some(&decl)); - let body_expr = body(self); - let body_id = self.record_body(body_expr, arguments); - self.is_generator = prev_is_generator; - self.is_async_body = prev_is_async_body; - - let capture_clause = self.lower_capture_clause(capture_clause); - let decl = self.lower_fn_decl(&decl, None, /* impl trait allowed */ false, None); + let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None); + let body_id = self.lower_fn_body(&ast_decl, |this| { + this.is_async_body = true; + body(this) + }); let generator = hir::Expr { hir_id: self.lower_node_id(closure_node_id), node: hir::ExprKind::Closure(capture_clause, decl, body_id, span, @@ -1154,7 +1144,7 @@ impl<'a> LoweringContext<'a> { attrs: ThinVec::new(), }; - let unstable_span = self.sess.source_map().mark_span_with_reason( + let unstable_span = self.mark_span_with_reason( CompilerDesugaringKind::Async, span, Some(vec![sym::gen_future].into()), @@ -1164,18 +1154,32 @@ impl<'a> LoweringContext<'a> { hir::ExprKind::Call(P(gen_future), hir_vec![generator]) } - fn lower_body(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId - where - F: FnOnce(&mut LoweringContext<'_>) -> hir::Expr, - { - let prev_generator = mem::replace(&mut self.is_generator, false); - let prev_async = mem::replace(&mut self.is_async_body, false); - let arguments = self.lower_args(decl); - let result = f(self); - let r = self.record_body(result, arguments); - self.is_generator = prev_generator; - self.is_async_body = prev_async; - return r; + fn lower_body( + &mut self, + f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec, hir::Expr), + ) -> hir::BodyId { + let prev_is_generator = mem::replace(&mut self.is_generator, false); + let prev_is_async_body = mem::replace(&mut self.is_async_body, false); + let (arguments, result) = f(self); + let body_id = self.record_body(arguments, result); + self.is_generator = prev_is_generator; + self.is_async_body = prev_is_async_body; + body_id + } + + fn lower_fn_body( + &mut self, + decl: &FnDecl, + body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr, + ) -> hir::BodyId { + self.lower_body(|this| ( + decl.inputs.iter().map(|x| this.lower_arg(x)).collect(), + body(this), + )) + } + + fn lower_const_body(&mut self, expr: &Expr) -> hir::BodyId { + self.lower_body(|this| (hir_vec![], this.lower_expr(expr))) } fn with_loop_scope(&mut self, loop_id: NodeId, f: F) -> T @@ -1561,7 +1565,7 @@ impl<'a> LoweringContext<'a> { // desugaring that explicitly states that we don't want to track that. // Not tracking it makes lints in rustc and clippy very fragile as // frequently opened issues show. - let exist_ty_span = self.sess.source_map().mark_span_with_reason( + let exist_ty_span = self.mark_span_with_reason( CompilerDesugaringKind::ExistentialReturnType, span, None, @@ -2266,17 +2270,10 @@ impl<'a> LoweringContext<'a> { init: l.init.as_ref().map(|e| P(self.lower_expr(e))), span: l.span, attrs: l.attrs.clone(), - source: self.lower_local_source(l.source), + source: hir::LocalSource::Normal, }, ids) } - fn lower_local_source(&mut self, ls: LocalSource) -> hir::LocalSource { - match ls { - LocalSource::Normal => hir::LocalSource::Normal, - LocalSource::AsyncFn => hir::LocalSource::AsyncFn, - } - } - fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability { match m { Mutability::Mutable => hir::MutMutable, @@ -2284,22 +2281,10 @@ impl<'a> LoweringContext<'a> { } } - fn lower_args(&mut self, decl: Option<&FnDecl>) -> HirVec { - decl.map_or(hir_vec![], |decl| decl.inputs.iter().map(|x| self.lower_arg(x)).collect()) - } - fn lower_arg(&mut self, arg: &Arg) -> hir::Arg { hir::Arg { hir_id: self.lower_node_id(arg.id), pat: self.lower_pat(&arg.pat), - source: self.lower_arg_source(&arg.source), - } - } - - fn lower_arg_source(&mut self, source: &ArgSource) -> hir::ArgSource { - match source { - ArgSource::Normal => hir::ArgSource::Normal, - ArgSource::AsyncFn(pat) => hir::ArgSource::AsyncFn(self.lower_pat(pat)), } } @@ -2435,7 +2420,7 @@ impl<'a> LoweringContext<'a> { ) -> hir::FunctionRetTy { let span = output.span(); - let exist_ty_span = self.sess.source_map().mark_span_with_reason( + let exist_ty_span = self.mark_span_with_reason( CompilerDesugaringKind::Async, span, None, @@ -2998,11 +2983,14 @@ impl<'a> LoweringContext<'a> { bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect() } - fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P { + fn lower_block_with_stmts( + &mut self, + b: &Block, + targeted_by_break: bool, + mut stmts: Vec, + ) -> P { let mut expr = None; - let mut stmts = vec![]; - for (index, stmt) in b.stmts.iter().enumerate() { if index == b.stmts.len() - 1 { if let StmtKind::Expr(ref e) = stmt.node { @@ -3025,56 +3013,136 @@ impl<'a> LoweringContext<'a> { }) } - fn lower_async_body( + fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P { + self.lower_block_with_stmts(b, targeted_by_break, vec![]) + } + + fn lower_maybe_async_body( &mut self, decl: &FnDecl, - asyncness: &IsAsync, + asyncness: IsAsync, body: &Block, ) -> hir::BodyId { - self.lower_body(Some(&decl), |this| { - if let IsAsync::Async { closure_id, ref arguments, .. } = asyncness { - let mut body = body.clone(); + let closure_id = match asyncness { + IsAsync::Async { closure_id, .. } => closure_id, + IsAsync::NotAsync => return self.lower_fn_body(&decl, |this| { + let body = this.lower_block(body, false); + this.expr_block(body, ThinVec::new()) + }), + }; - // 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. - // - // async fn foo(: , : , : ) { - // async move { - // } - // } - // - // // ...becomes... - // fn foo(__arg0: , __arg1: , __arg2: ) { - // async move { - // let __arg2 = __arg2; - // let = __arg2; - // let __arg1 = __arg1; - // let = __arg1; - // let __arg0 = __arg0; - // let = __arg0; - // } - // } + self.lower_body(|this| { + let mut arguments: Vec = Vec::new(); + let mut statements: Vec = Vec::new(); + + // 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 { + // } + // } + // + // into: + // + // fn foo(__arg0: , __arg1: , __arg2: ) { + // async move { + // let __arg2 = __arg2; + // let = __arg2; + // let __arg1 = __arg1; + // let = __arg1; + // let __arg0 = __arg0; + // let = __arg0; + // } + // } + // + // If `` is a simple ident, then it is lowered to a single + // `let = ;` statement as an optimization. + for (index, argument) in decl.inputs.iter().enumerate() { + let argument = this.lower_arg(argument); + let span = argument.pat.span; + + // Check if this is a binding pattern, if so, we can optimize and avoid adding a + // `let = __argN;` statement. In this case, we do not rename the argument. + let (ident, is_simple_argument) = match argument.pat.node { + hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) => + (ident, true), + _ => { + // Replace the ident for bindings that aren't simple. + let name = format!("__arg{}", index); + let ident = Ident::from_str(&name); + + (ident, false) + }, + }; + + 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 `` is a simple ident, then it is lowered to a single - // `let = ;` statement as an optimization. - for a in arguments.iter().rev() { - if let Some(pat_stmt) = a.pat_stmt.clone() { - body.stmts.insert(0, pat_stmt); - } - body.stmts.insert(0, a.move_stmt.clone()); - } + // 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_pat, new_argument_id) = this.pat_ident(desugared_span, ident); + let new_argument = hir::Arg { + hir_id: argument.hir_id, + pat: new_argument_pat, + }; - let async_expr = this.make_async_expr( - CaptureBy::Value, *closure_id, None, body.span, - |this| { - let body = this.lower_block(&body, false); - this.expr_block(body, ThinVec::new()) - }); - this.expr(body.span, async_expr, ThinVec::new()) - } else { - let body = this.lower_block(body, false); - this.expr_block(body, ThinVec::new()) + 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. + 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); + statements.push(stmt); + } else { + // If this is not the simple case, then we construct two statements: + // + // ``` + // let __argN = __argN; + // let = __argN; + // ``` + // + // The first statement moves the argument into the closure and thus ensures + // that the drop order is correct. + // + // The second statement creates the bindings that the user wrote. + + // 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 (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_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); + + statements.push(move_stmt); + statements.push(pattern_stmt); + }; + + arguments.push(new_argument); } + + let async_expr = this.make_async_expr( + CaptureBy::Value, closure_id, None, body.span, + |this| { + let body = this.lower_block_with_stmts(body, false, statements); + this.expr_block(body, ThinVec::new()) + }); + (HirVec::from(arguments), this.expr(body.span, async_expr, ThinVec::new())) }) } @@ -3098,7 +3166,6 @@ impl<'a> LoweringContext<'a> { self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs) } ItemKind::Static(ref t, m, ref e) => { - let value = self.lower_body(None, |this| this.lower_expr(e)); hir::ItemKind::Static( self.lower_ty( t, @@ -3109,11 +3176,10 @@ impl<'a> LoweringContext<'a> { } ), self.lower_mutability(m), - value, + self.lower_const_body(e), ) } ItemKind::Const(ref t, ref e) => { - let value = self.lower_body(None, |this| this.lower_expr(e)); hir::ItemKind::Const( self.lower_ty( t, @@ -3123,50 +3189,31 @@ impl<'a> LoweringContext<'a> { ImplTraitContext::Disallowed(ImplTraitPosition::Binding) } ), - value + self.lower_const_body(e) ) } - ItemKind::Fn(ref decl, ref header, ref generics, ref body) => { + ItemKind::Fn(ref decl, header, ref generics, ref body) => { let fn_def_id = self.resolver.definitions().local_def_id(id); self.with_new_scopes(|this| { this.current_item = Some(ident.span); - let mut lower_fn = |decl: &FnDecl| { - // Note: we don't need to change the return type from `T` to - // `impl Future` here because lower_body - // only cares about the input argument patterns in the function - // declaration (decl), not the return types. - let body_id = this.lower_async_body(&decl, &header.asyncness.node, body); - - let (generics, fn_decl) = this.add_in_band_defs( - generics, - fn_def_id, - AnonymousLifetimeMode::PassThrough, - |this, idty| this.lower_fn_decl( - &decl, - Some((fn_def_id, idty)), - true, - header.asyncness.node.opt_return_id() - ), - ); - (body_id, generics, fn_decl) - }; + // Note: we don't need to change the return type from `T` to + // `impl Future` here because lower_body + // only cares about the input argument patterns in the function + // declaration (decl), not the return types. + let body_id = this.lower_maybe_async_body(&decl, header.asyncness.node, body); - let (body_id, generics, fn_decl) = if let IsAsync::Async { - arguments, .. - } = &header.asyncness.node { - let mut decl = decl.clone(); - // Replace the arguments of this async function with the generated - // arguments that will be moved into the closure. - for (i, a) in arguments.clone().drain(..).enumerate() { - if let Some(arg) = a.arg { - decl.inputs[i] = arg; - } - } - lower_fn(&decl) - } else { - lower_fn(decl) - }; + let (generics, fn_decl) = this.add_in_band_defs( + generics, + fn_def_id, + AnonymousLifetimeMode::PassThrough, + |this, idty| this.lower_fn_decl( + &decl, + Some((fn_def_id, idty)), + true, + header.asyncness.node.opt_return_id() + ), + ); hir::ItemKind::Fn( fn_decl, @@ -3548,7 +3595,7 @@ impl<'a> LoweringContext<'a> { self.lower_ty(ty, ImplTraitContext::disallowed()), default .as_ref() - .map(|x| self.lower_body(None, |this| this.lower_expr(x))), + .map(|x| self.lower_const_body(x)), ), ), TraitItemKind::Method(ref sig, None) => { @@ -3563,7 +3610,7 @@ impl<'a> LoweringContext<'a> { (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names))) } TraitItemKind::Method(ref sig, Some(ref body)) => { - let body_id = self.lower_body(Some(&sig.decl), |this| { + let body_id = self.lower_fn_body(&sig.decl, |this| { let body = this.lower_block(body, false); this.expr_block(body, ThinVec::new()) }); @@ -3627,48 +3674,26 @@ impl<'a> LoweringContext<'a> { let impl_item_def_id = self.resolver.definitions().local_def_id(i.id); let (generics, node) = match i.node { - ImplItemKind::Const(ref ty, ref expr) => { - let body_id = self.lower_body(None, |this| this.lower_expr(expr)); - ( - self.lower_generics(&i.generics, ImplTraitContext::disallowed()), - hir::ImplItemKind::Const( - self.lower_ty(ty, ImplTraitContext::disallowed()), - body_id, - ), - ) - } + ImplItemKind::Const(ref ty, ref expr) => ( + self.lower_generics(&i.generics, ImplTraitContext::disallowed()), + hir::ImplItemKind::Const( + self.lower_ty(ty, ImplTraitContext::disallowed()), + self.lower_const_body(expr), + ), + ), ImplItemKind::Method(ref sig, ref body) => { - let mut lower_method = |sig: &MethodSig| { - let body_id = self.lower_async_body( - &sig.decl, &sig.header.asyncness.node, body - ); - let impl_trait_return_allow = !self.is_in_trait_impl; - let (generics, sig) = self.lower_method_sig( - &i.generics, - sig, - impl_item_def_id, - impl_trait_return_allow, - sig.header.asyncness.node.opt_return_id(), - ); - (body_id, generics, sig) - }; - - let (body_id, generics, sig) = if let IsAsync::Async { - ref arguments, .. - } = sig.header.asyncness.node { - let mut sig = sig.clone(); - // Replace the arguments of this async function with the generated - // arguments that will be moved into the closure. - for (i, a) in arguments.clone().drain(..).enumerate() { - if let Some(arg) = a.arg { - sig.decl.inputs[i] = arg; - } - } - lower_method(&sig) - } else { - lower_method(sig) - }; self.current_item = Some(i.span); + let body_id = self.lower_maybe_async_body( + &sig.decl, sig.header.asyncness.node, body + ); + let impl_trait_return_allow = !self.is_in_trait_impl; + let (generics, sig) = self.lower_method_sig( + &i.generics, + sig, + impl_item_def_id, + impl_trait_return_allow, + sig.header.asyncness.node.opt_return_id(), + ); (generics, hir::ImplItemKind::Method(sig, body_id)) } @@ -3860,7 +3885,7 @@ impl<'a> LoweringContext<'a> { impl_trait_return_allow: bool, is_async: Option, ) -> (hir::Generics, hir::MethodSig) { - let header = self.lower_fn_header(&sig.header); + let header = self.lower_fn_header(sig.header); let (generics, decl) = self.add_in_band_defs( generics, fn_def_id, @@ -3882,10 +3907,10 @@ impl<'a> LoweringContext<'a> { } } - fn lower_fn_header(&mut self, h: &FnHeader) -> hir::FnHeader { + fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader { hir::FnHeader { unsafety: self.lower_unsafety(h.unsafety), - asyncness: self.lower_asyncness(&h.asyncness.node), + asyncness: self.lower_asyncness(h.asyncness.node), constness: self.lower_constness(h.constness), abi: h.abi, } @@ -3905,7 +3930,7 @@ impl<'a> LoweringContext<'a> { } } - fn lower_asyncness(&mut self, a: &IsAsync) -> hir::IsAsync { + fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync { match a { IsAsync::Async { .. } => hir::IsAsync::Async, IsAsync::NotAsync => hir::IsAsync::NotAsync, @@ -4064,7 +4089,7 @@ impl<'a> LoweringContext<'a> { self.with_new_scopes(|this| { hir::AnonConst { hir_id: this.lower_node_id(c.id), - body: this.lower_body(None, |this| this.lower_expr(&c.value)), + body: this.lower_const_body(&c.value), } }) } @@ -4151,10 +4176,7 @@ impl<'a> LoweringContext<'a> { let else_arm = self.arm(hir_vec![else_pat], P(else_expr)); // Lower condition: - let span_block = self - .sess - .source_map() - .mark_span_with_reason(IfTemporary, cond.span, None); + let span_block = self.mark_span_with_reason(IfTemporary, cond.span, None); let cond = self.lower_expr(cond); // Wrap in a construct equivalent to `{ let _t = $cond; _t }` to preserve drop // semantics since `if cond { ... }` don't let temporaries live outside of `cond`. @@ -4184,7 +4206,7 @@ impl<'a> LoweringContext<'a> { }), ExprKind::TryBlock(ref body) => { self.with_catch_scope(body.id, |this| { - let unstable_span = this.sess.source_map().mark_span_with_reason( + let unstable_span = this.mark_span_with_reason( CompilerDesugaringKind::TryBlock, body.span, Some(vec![sym::try_trait].into()), @@ -4222,7 +4244,7 @@ impl<'a> LoweringContext<'a> { } ExprKind::Await(_origin, ref expr) => self.lower_await(e.span, expr), ExprKind::Closure( - capture_clause, ref asyncness, movability, ref decl, ref body, fn_decl_span + capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span ) => { if let IsAsync::Async { closure_id, .. } = asyncness { let outer_decl = FnDecl { @@ -4255,12 +4277,12 @@ impl<'a> LoweringContext<'a> { // Transform `async |x: u8| -> X { ... }` into // `|x: u8| future_from_generator(|| -> X { ... })`. - let body_id = this.lower_body(Some(&outer_decl), |this| { + let body_id = this.lower_fn_body(&outer_decl, |this| { let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output { Some(&**ty) } else { None }; let async_body = this.make_async_expr( - capture_clause, *closure_id, async_ret_ty, body.span, + capture_clause, closure_id, async_ret_ty, body.span, |this| { this.with_new_scopes(|this| this.lower_expr(body)) }); @@ -4281,7 +4303,7 @@ impl<'a> LoweringContext<'a> { self.with_new_scopes(|this| { this.current_item = Some(fn_decl_span); let mut is_generator = false; - let body_id = this.lower_body(Some(decl), |this| { + let body_id = this.lower_fn_body(decl, |this| { let e = this.lower_expr(body); is_generator = this.is_generator; e @@ -4616,7 +4638,7 @@ impl<'a> LoweringContext<'a> { // expand let mut head = self.lower_expr(head); let head_sp = head.span; - let desugared_span = self.sess.source_map().mark_span_with_reason( + let desugared_span = self.mark_span_with_reason( CompilerDesugaringKind::ForLoop, head_sp, None, @@ -4770,13 +4792,13 @@ impl<'a> LoweringContext<'a> { // return Try::from_error(From::from(err)), // } - let unstable_span = self.sess.source_map().mark_span_with_reason( + let unstable_span = self.mark_span_with_reason( CompilerDesugaringKind::QuestionMark, e.span, Some(vec![sym::try_trait].into()), ); let try_span = self.sess.source_map().end_point(e.span); - let try_span = self.sess.source_map().mark_span_with_reason( + let try_span = self.mark_span_with_reason( CompilerDesugaringKind::QuestionMark, try_span, Some(vec![sym::try_trait].into()), @@ -5573,12 +5595,12 @@ impl<'a> LoweringContext<'a> { err.emit(); return hir::ExprKind::Err; } - let span = self.sess.source_map().mark_span_with_reason( + let span = self.mark_span_with_reason( CompilerDesugaringKind::Await, await_span, None, ); - let gen_future_span = self.sess.source_map().mark_span_with_reason( + let gen_future_span = self.mark_span_with_reason( CompilerDesugaringKind::Await, await_span, Some(vec![sym::gen_future].into()), diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index bde27c71f9a6d..a4484c8173898 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -64,17 +64,16 @@ impl<'a> DefCollector<'a> { id: NodeId, name: Name, span: Span, - header: &'a FnHeader, + header: &FnHeader, generics: &'a Generics, decl: &'a FnDecl, body: &'a Block, ) { - let (closure_id, return_impl_trait_id, arguments) = match &header.asyncness.node { + let (closure_id, return_impl_trait_id) = match header.asyncness.node { IsAsync::Async { closure_id, return_impl_trait_id, - arguments, - } => (closure_id, return_impl_trait_id, arguments), + } => (closure_id, return_impl_trait_id), _ => unreachable!(), }; @@ -83,38 +82,16 @@ impl<'a> DefCollector<'a> { let fn_def_data = DefPathData::ValueNs(name.as_interned_str()); let fn_def = self.create_def(id, fn_def_data, span); return self.with_parent(fn_def, |this| { - this.create_def(*return_impl_trait_id, DefPathData::ImplTrait, span); + this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); visit::walk_generics(this, generics); - - // Walk the generated arguments for the `async fn`. - for (i, a) in arguments.iter().enumerate() { - use visit::Visitor; - if let Some(arg) = &a.arg { - this.visit_ty(&arg.ty); - } else { - this.visit_ty(&decl.inputs[i].ty); - } - } - - // We do not invoke `walk_fn_decl` as this will walk the arguments that are being - // replaced. - visit::walk_fn_ret_ty(this, &decl.output); + visit::walk_fn_decl(this, decl); let closure_def = this.create_def( - *closure_id, DefPathData::ClosureExpr, span, + closure_id, DefPathData::ClosureExpr, span, ); this.with_parent(closure_def, |this| { - use visit::Visitor; - // Walk each of the generated statements before the regular block body. - for a in arguments { - this.visit_stmt(&a.move_stmt); - if let Some(pat_stmt) = &a.pat_stmt { - this.visit_stmt(&pat_stmt); - } - } - - visit::walk_block(this, &body); + visit::walk_block(this, body); }) }) } @@ -302,7 +279,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { match expr.node { ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id), - ExprKind::Closure(_, ref asyncness, ..) => { + ExprKind::Closure(_, asyncness, ..) => { let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span); @@ -311,7 +288,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { // Async closures desugar to closures inside of closures, so // we must create two defs. if let IsAsync::Async { closure_id, .. } = asyncness { - let async_def = self.create_def(*closure_id, + let async_def = self.create_def(closure_id, DefPathData::ClosureExpr, expr.span); self.parent_def = Some(async_def); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 210c0c9225a3d..65fc56f2c4878 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1929,26 +1929,6 @@ pub struct InlineAsm { pub struct Arg { pub pat: P, pub hir_id: HirId, - pub source: ArgSource, -} - -impl Arg { - /// Returns the pattern representing the original binding for this argument. - pub fn original_pat(&self) -> &P { - match &self.source { - ArgSource::Normal => &self.pat, - ArgSource::AsyncFn(pat) => &pat, - } - } -} - -/// Represents the source of an argument in a function header. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] -pub enum ArgSource { - /// Argument as specified by the user. - Normal, - /// Generated argument from `async fn` lowering, contains the original binding pattern. - AsyncFn(P), } /// Represents the header (not the body) of a function declaration. diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index 944cc8a8b1999..ecdcb4bbf114a 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -86,12 +86,12 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { let sub_is_ret_type = self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub); - let span_label_var1 = match anon_arg_sup.original_pat().simple_ident() { + let span_label_var1 = match anon_arg_sup.pat.simple_ident() { Some(simple_ident) => format!(" from `{}`", simple_ident), None => String::new(), }; - let span_label_var2 = match anon_arg_sub.original_pat().simple_ident() { + let span_label_var2 = match anon_arg_sub.pat.simple_ident() { Some(simple_ident) => format!(" into `{}`", simple_ident), None => String::new(), }; diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 2d7587b11b6f8..0efc124e31fee 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -95,7 +95,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { } } - let (error_var, span_label_var) = match arg.original_pat().simple_ident() { + let (error_var, span_label_var) = match arg.pat.simple_ident() { Some(simple_ident) => ( format!("the type of `{}`", simple_ident), format!("the type of `{}`", simple_ident), diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c6583dd7a27b7..c5c6c4b944700 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1335,30 +1335,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> run_early_pass!(self, check_mac, mac); } - - fn visit_fn_header(&mut self, header: &'a ast::FnHeader) { - // Unlike in HIR lowering and name resolution, the `AsyncArgument` statements are not added - // to the function body and the arguments do not replace those in the declaration. They are - // still visited manually here so that buffered lints can be emitted. - if let ast::IsAsync::Async { ref arguments, .. } = header.asyncness.node { - for a in arguments { - // Visit the argument.. - if let Some(arg) = &a.arg { - self.visit_pat(&arg.pat); - if let ast::ArgSource::AsyncFn(pat) = &arg.source { - self.visit_pat(pat); - } - self.visit_ty(&arg.ty); - } - - // ..and the statement. - self.visit_stmt(&a.move_stmt); - if let Some(pat_stmt) = &a.pat_stmt { - self.visit_stmt(&pat_stmt); - } - } - } - } } struct LateLintPassObjects<'a> { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 593a09b6866db..7c57c50595bc8 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2414,9 +2414,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { have_bound_regions, } = info; - let help_name = if let Some(body) = parent { - let arg = &self.tcx.hir().body(body).arguments[index]; - format!("`{}`", self.tcx.hir().hir_to_pretty_string(arg.original_pat().hir_id)) + let help_name = if let Some(ident) = parent.and_then(|body| { + self.tcx.hir().body(body).arguments[index].pat.simple_ident() + }) { + format!("`{}`", ident) } else { format!("argument {}", index + 1) }; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d565a08927241..919d575f21fe6 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -126,6 +126,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Body<' opt_ty_info = None; self_arg = None; } + ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&*arg.pat), self_arg) }); @@ -614,10 +615,7 @@ fn should_abort_on_panic<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, /////////////////////////////////////////////////////////////////////////// /// the main entry point for building MIR for a function -struct ArgInfo<'gcx>(Ty<'gcx>, - Option, - Option<&'gcx hir::Pat>, - Option); +struct ArgInfo<'gcx>(Ty<'gcx>, Option, Option<&'gcx hir::Pat>, Option); fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, fn_id: hir::HirId, @@ -883,21 +881,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // debuginfo and so that error reporting knows that this is a user // variable. For any other pattern the pattern introduces new // variables which will be named instead. - let mut name = None; - if let Some(pat) = pattern { - match pat.node { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) - | hir::PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, _) => { - name = Some(ident.name); - } - _ => (), - } - } - - let source_info = SourceInfo { - scope: OUTERMOST_SOURCE_SCOPE, - span: pattern.map_or(self.fn_span, |pat| pat.span) + let (name, span) = if let Some(pat) = pattern { + (pat.simple_ident().map(|ident| ident.name), pat.span) + } else { + (None, self.fn_span) }; + + let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span, }; self.local_decls.push(LocalDecl { mutability: Mutability::Mut, ty, @@ -931,7 +921,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match *pattern.kind { // Don't introduce extra copies for simple bindings - PatternKind::Binding { mutability, var, mode: BindingMode::ByValue, .. } => { + PatternKind::Binding { + mutability, + var, + mode: BindingMode::ByValue, + subpattern: None, + .. + } => { self.local_decls[local].mutability = mutability; self.local_decls[local].is_user_variable = if let Some(kind) = self_binding { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 2afcbe8a15137..89c4a9106a477 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -222,7 +222,7 @@ impl<'a> AstValidator<'a> { } } - fn check_trait_fn_not_async(&self, span: Span, asyncness: &IsAsync) { + fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) { if asyncness.is_async() { struct_span_err!(self.session, span, E0706, "trait fns cannot be declared `async`").emit() @@ -561,7 +561,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.invalid_visibility(&impl_item.vis, None); if let ImplItemKind::Method(ref sig, _) = impl_item.node { self.check_trait_fn_not_const(sig.header.constness); - self.check_trait_fn_not_async(impl_item.span, &sig.header.asyncness.node); + self.check_trait_fn_not_async(impl_item.span, sig.header.asyncness.node); } } } @@ -633,7 +633,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.no_questions_in_bounds(bounds, "supertraits", true); for trait_item in trait_items { if let TraitItemKind::Method(ref sig, ref block) = trait_item.node { - self.check_trait_fn_not_async(trait_item.span, &sig.header.asyncness.node); + self.check_trait_fn_not_async(trait_item.span, sig.header.asyncness.node); self.check_trait_fn_not_const(sig.header.constness); if block.is_none() { self.check_decl_no_pat(&sig.decl, |span, mut_ident| { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 20e18d60f076b..f084d3b9f28c3 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -948,16 +948,6 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { intravisit::walk_pat(self, pat); } - - fn visit_argument_source(&mut self, s: &'tcx hir::ArgSource) { - match s { - // Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has - // a `NodeId` w/out a type, as it is only used for getting the name of the original - // pattern for diagnostics where only an `hir::Arg` is present. - hir::ArgSource::AsyncFn(..) => {}, - _ => intravisit::walk_argument_source(self, s), - } - } } //////////////////////////////////////////////////////////////////////////////////////////// @@ -1147,16 +1137,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { intravisit::walk_pat(self, pattern); } - fn visit_argument_source(&mut self, s: &'tcx hir::ArgSource) { - match s { - // Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has - // a `NodeId` w/out a type, as it is only used for getting the name of the original - // pattern for diagnostics where only an `hir::Arg` is present. - hir::ArgSource::AsyncFn(..) => {}, - _ => intravisit::walk_argument_source(self, s), - } - } - fn visit_local(&mut self, local: &'tcx hir::Local) { if let Some(ref init) = local.init { if self.check_expr_pat_type(init.hir_id, init.span) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 21e759ccc650e..99abe69017da7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -855,15 +855,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { _: NodeId) { debug!("(resolving function) entering function"); - let (rib_kind, asyncness) = match function_kind { - FnKind::ItemFn(_, ref header, ..) => - (FnItemRibKind, &header.asyncness.node), - FnKind::Method(_, ref sig, _, _) => - (AssocItemRibKind, &sig.header.asyncness.node), - FnKind::Closure(_) => - // Async closures aren't resolved through `visit_fn`-- they're - // processed separately - (NormalRibKind, &IsAsync::NotAsync), + let rib_kind = match function_kind { + FnKind::ItemFn(..) => FnItemRibKind, + FnKind::Method(..) => AssocItemRibKind, + FnKind::Closure(_) => NormalRibKind, }; // Create a value rib for the function. @@ -874,45 +869,20 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { // Add each argument to the rib. let mut bindings_list = FxHashMap::default(); - let mut add_argument = |argument: &ast::Arg| { + for argument in &declaration.inputs { self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list); + self.visit_ty(&argument.ty); - debug!("(resolving function) recorded argument"); - }; - // Walk the generated async arguments if this is an `async fn`, otherwise walk the - // normal arguments. - if let IsAsync::Async { ref arguments, .. } = asyncness { - for (i, a) in arguments.iter().enumerate() { - if let Some(arg) = &a.arg { - add_argument(&arg); - } else { - add_argument(&declaration.inputs[i]); - } - } - } else { - for a in &declaration.inputs { add_argument(a); } + debug!("(resolving function) recorded argument"); } - visit::walk_fn_ret_ty(self, &declaration.output); // Resolve the function body, potentially inside the body of an async closure match function_kind { - FnKind::ItemFn(.., body) | FnKind::Method(.., body) => { - if let IsAsync::Async { ref arguments, .. } = asyncness { - let mut body = body.clone(); - // Insert the generated statements into the body before attempting to - // resolve names. - for a in arguments.iter().rev() { - if let Some(pat_stmt) = a.pat_stmt.clone() { - body.stmts.insert(0, pat_stmt); - } - body.stmts.insert(0, a.move_stmt.clone()); - } - self.visit_block(&body); - } else { - self.visit_block(body); - } + FnKind::ItemFn(.., body) | + FnKind::Method(.., body) => { + self.visit_block(body); } FnKind::Closure(body) => { self.visit_expr(body); @@ -4178,7 +4148,7 @@ impl<'a> Resolver<'a> { let add_module_candidates = |module: Module<'_>, names: &mut Vec| { for (&(ident, _), resolution) in module.resolutions.borrow().iter() { if let Some(binding) = resolution.borrow().binding { - if !ident.is_gensymed() && filter_fn(binding.res()) { + if filter_fn(binding.res()) { names.push(TypoSuggestion { candidate: ident.name, article: binding.res().article(), @@ -4196,7 +4166,7 @@ impl<'a> Resolver<'a> { for rib in self.ribs[ns].iter().rev() { // Locals and type parameters for (ident, &res) in &rib.bindings { - if !ident.is_gensymed() && filter_fn(res) { + if filter_fn(res) { names.push(TypoSuggestion { candidate: ident.name, article: res.article(), @@ -4226,7 +4196,7 @@ impl<'a> Resolver<'a> { }, ); - if !ident.is_gensymed() && filter_fn(crate_mod) { + if filter_fn(crate_mod) { Some(TypoSuggestion { candidate: ident.name, article: "a", @@ -4249,15 +4219,13 @@ impl<'a> Resolver<'a> { // Add primitive types to the mix if filter_fn(Res::PrimTy(Bool)) { names.extend( - self.primitive_type_table.primitive_types - .iter() - .map(|(name, _)| { - TypoSuggestion { - candidate: *name, - article: "a", - kind: "primitive type", - } - }) + self.primitive_type_table.primitive_types.iter().map(|(name, _)| { + TypoSuggestion { + candidate: *name, + article: "a", + kind: "primitive type", + } + }) ) } } else { diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 109863f8a56b2..db8b5eacd94d9 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -374,7 +374,7 @@ impl Sig for ast::Item { Ok(extend_sig(ty, text, defs, vec![])) } - ast::ItemKind::Fn(ref decl, ref header, ref generics, _) => { + ast::ItemKind::Fn(ref decl, header, ref generics, _) => { let mut text = String::new(); if header.constness.node == ast::Constness::Const { text.push_str("const "); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 82d198f0b78f7..3ada80b3e8b70 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1009,16 +1009,6 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { // Don't descend into the bodies of nested closures fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl, _: hir::BodyId, _: Span, _: hir::HirId) { } - - fn visit_argument_source(&mut self, s: &'gcx hir::ArgSource) { - match s { - // Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has - // a `NodeId` w/out a type, as it is only used for getting the name of the original - // pattern for diagnostics where only an `hir::Arg` is present. - hir::ArgSource::AsyncFn(..) => {}, - _ => intravisit::walk_argument_source(self, s), - } - } } /// When `check_fn` is invoked on a generator (i.e., a body that diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index a535f776dfe60..6f8682e64671c 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -311,16 +311,6 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { let ty = self.resolve(&ty, &hir_ty.span); self.write_ty_to_tables(hir_ty.hir_id, ty); } - - fn visit_argument_source(&mut self, s: &'gcx hir::ArgSource) { - match s { - // Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has - // a `NodeId` w/out a type, as it is only used for getting the name of the original - // pattern for diagnostics where only an `hir::Arg` is present. - hir::ArgSource::AsyncFn(..) => {}, - _ => intravisit::walk_argument_source(self, s), - } - } } impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e68ad6a7c3b4b..0c00b3b20b5b3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2019,7 +2019,7 @@ impl<'a> Clean for (&'a [hir::Ty], hir::BodyId) { Arguments { values: self.0.iter().enumerate().map(|(i, ty)| { Argument { - name: name_from_pat(&body.arguments[i].original_pat()), + name: name_from_pat(&body.arguments[i].pat), type_: ty.clean(cx), } }).collect() diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 75e83bd9f9c74..b8a10d90c3c0a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -879,17 +879,6 @@ pub struct Local { pub id: NodeId, pub span: Span, pub attrs: ThinVec, - /// Origin of this local variable. - pub source: LocalSource, -} - -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] -pub enum LocalSource { - /// Local was parsed from source. - Normal, - /// Within `ast::IsAsync::Async`, a local is generated that will contain the moved arguments - /// of an `async fn`. - AsyncFn, } /// An arm of a 'match'. @@ -1770,16 +1759,6 @@ pub struct Arg { pub ty: P, pub pat: P, pub id: NodeId, - pub source: ArgSource, -} - -/// The source of an argument in a function header. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub enum ArgSource { - /// Argument as written by the user. - Normal, - /// Argument from `async fn` lowering, contains the original binding pattern. - AsyncFn(P), } /// Alternative representation for `Arg`s describing `self` parameter of methods. @@ -1839,7 +1818,6 @@ impl Arg { }), ty, id: DUMMY_NODE_ID, - source: ArgSource::Normal, }; match eself.node { SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty), @@ -1894,39 +1872,18 @@ pub enum Unsafety { Normal, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct AsyncArgument { - /// `__arg0` - pub ident: Ident, - /// `__arg0: ` argument to replace existing function argument `: `. Only if - /// argument is not a simple binding. - pub arg: Option, - /// `let __arg0 = __arg0;` statement to be inserted at the start of the block. - pub move_stmt: Stmt, - /// `let = __arg0;` statement to be inserted at the start of the block, after matching - /// move statement. Only if argument is not a simple binding. - pub pat_stmt: Option, -} - -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] pub enum IsAsync { Async { closure_id: NodeId, return_impl_trait_id: NodeId, - /// This field stores the arguments and statements that are used in HIR lowering to - /// ensure that `async fn` arguments are dropped at the correct time. - /// - /// The argument and statements here are generated at parse time as they are required in - /// both the hir lowering, def collection and name resolution and this stops them needing - /// to be created in each place. - arguments: Vec, }, NotAsync, } impl IsAsync { - pub fn is_async(&self) -> bool { - if let IsAsync::Async { .. } = *self { + pub fn is_async(self) -> bool { + if let IsAsync::Async { .. } = self { true } else { false @@ -1934,12 +1891,12 @@ impl IsAsync { } /// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item. - pub fn opt_return_id(&self) -> Option { + pub fn opt_return_id(self) -> Option { match self { IsAsync::Async { return_impl_trait_id, .. - } => Some(*return_impl_trait_id), + } => Some(return_impl_trait_id), IsAsync::NotAsync => None, } } @@ -2279,7 +2236,7 @@ impl Item { /// /// All the information between the visibility and the name of the function is /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] pub struct FnHeader { pub unsafety: Unsafety, pub asyncness: Spanned, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9c0ffc1f6e8cb..47c79f8466a95 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -516,7 +516,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { id: ast::DUMMY_NODE_ID, span: sp, attrs: ThinVec::new(), - source: ast::LocalSource::Normal, }); ast::Stmt { id: ast::DUMMY_NODE_ID, @@ -545,7 +544,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { id: ast::DUMMY_NODE_ID, span: sp, attrs: ThinVec::new(), - source: ast::LocalSource::Normal, }); ast::Stmt { id: ast::DUMMY_NODE_ID, @@ -563,7 +561,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { id: ast::DUMMY_NODE_ID, span, attrs: ThinVec::new(), - source: ast::LocalSource::Normal, }); ast::Stmt { id: ast::DUMMY_NODE_ID, @@ -971,8 +968,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::Arg { ty, pat: arg_pat, - id: ast::DUMMY_NODE_ID, - source: ast::ArgSource::Normal, + id: ast::DUMMY_NODE_ID } } diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 8f24d11cfd5b0..c56c156182bd6 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -101,13 +101,6 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> { fn remove(&mut self, id: ast::NodeId) -> AstFragment { self.expanded_fragments.remove(&id).unwrap() } - - fn next_id(&mut self, id: &mut ast::NodeId) { - if self.monotonic { - assert_eq!(*id, ast::DUMMY_NODE_ID); - *id = self.cx.resolver.next_node_id() - } - } } impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { @@ -189,19 +182,9 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { noop_visit_block(block, self); for stmt in block.stmts.iter_mut() { - self.next_id(&mut stmt.id); - } - } - - fn visit_asyncness(&mut self, a: &mut ast::IsAsync) { - noop_visit_asyncness(a, self); - - if let ast::IsAsync::Async { ref mut arguments, .. } = a { - for argument in arguments.iter_mut() { - self.next_id(&mut argument.move_stmt.id); - if let Some(ref mut pat_stmt) = &mut argument.pat_stmt { - self.next_id(&mut pat_stmt.id); - } + if self.monotonic { + assert_eq!(stmt.id, ast::DUMMY_NODE_ID); + stmt.id = self.cx.resolver.next_node_id(); } } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 0016c0d4d7e2b..757513098995b 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -207,10 +207,6 @@ pub trait MutVisitor: Sized { noop_visit_local(l, self); } - fn visit_local_source(&mut self, l: &mut LocalSource) { - noop_visit_local_source(l, self); - } - fn visit_mac(&mut self, _mac: &mut Mac) { panic!("visit_mac disabled by default"); // N.B., see note about macros above. If you really want a visitor that @@ -234,10 +230,6 @@ pub trait MutVisitor: Sized { noop_visit_arg(a, self); } - fn visit_arg_source(&mut self, a: &mut ArgSource) { - noop_visit_arg_source(a, self); - } - fn visit_generics(&mut self, generics: &mut Generics) { noop_visit_generics(generics, self); } @@ -522,17 +514,13 @@ pub fn noop_visit_parenthesized_parameter_data(args: &mut Parenth } pub fn noop_visit_local(local: &mut P, vis: &mut T) { - let Local { id, pat, ty, init, span, attrs, source } = local.deref_mut(); + let Local { id, pat, ty, init, span, attrs } = local.deref_mut(); vis.visit_id(id); vis.visit_pat(pat); visit_opt(ty, |ty| vis.visit_ty(ty)); visit_opt(init, |init| vis.visit_expr(init)); vis.visit_span(span); visit_thin_attrs(attrs, vis); - vis.visit_local_source(source); -} - -pub fn noop_visit_local_source(_local_source: &mut LocalSource, _vis: &mut T) { } pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { @@ -571,18 +559,10 @@ pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { vis.visit_span(span); } -pub fn noop_visit_arg(Arg { id, pat, ty, source }: &mut Arg, vis: &mut T) { +pub fn noop_visit_arg(Arg { id, pat, ty }: &mut Arg, vis: &mut T) { vis.visit_id(id); vis.visit_pat(pat); vis.visit_ty(ty); - vis.visit_arg_source(source); -} - -pub fn noop_visit_arg_source(source: &mut ArgSource, vis: &mut T) { - match source { - ArgSource::Normal => {}, - ArgSource::AsyncFn(pat) => vis.visit_pat(pat), - } } pub fn noop_visit_tt(tt: &mut TokenTree, vis: &mut T) { @@ -690,25 +670,9 @@ pub fn noop_visit_interpolated(nt: &mut token::Nonterminal, vis: pub fn noop_visit_asyncness(asyncness: &mut IsAsync, vis: &mut T) { match asyncness { - IsAsync::Async { closure_id, return_impl_trait_id, ref mut arguments } => { + IsAsync::Async { closure_id, return_impl_trait_id } => { vis.visit_id(closure_id); vis.visit_id(return_impl_trait_id); - for AsyncArgument { ident, arg, pat_stmt, move_stmt } in arguments.iter_mut() { - vis.visit_ident(ident); - if let Some(arg) = arg { - vis.visit_arg(arg); - } - visit_clobber(move_stmt, |stmt| { - vis.flat_map_stmt(stmt) - .expect_one("expected visitor to produce exactly one item") - }); - visit_opt(pat_stmt, |stmt| { - visit_clobber(stmt, |stmt| { - vis.flat_map_stmt(stmt) - .expect_one("expected visitor to produce exactly one item") - }) - }); - } } IsAsync::NotAsync => {} } diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index af9092dd5b05a..5df22f28797a4 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -27,7 +27,7 @@ crate fn dummy_arg(ident: Ident) -> Arg { span: ident.span, id: ast::DUMMY_NODE_ID }; - Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal } + Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID } } pub enum Error { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 671b313c7f24b..ae1e5116c676e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1,9 +1,9 @@ // ignore-tidy-filelength -use crate::ast::{AngleBracketedArgs, AsyncArgument, ParenthesizedArgs, AttrStyle, BareFnTy}; +use crate::ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy}; use crate::ast::{GenericBound, TraitBoundModifier}; use crate::ast::Unsafety; -use crate::ast::{Mod, AnonConst, Arg, ArgSource, Arm, Guard, Attribute, BindingMode, TraitItemKind}; +use crate::ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind}; use crate::ast::Block; use crate::ast::{BlockCheckMode, CaptureBy, Movability}; use crate::ast::{Constness, Crate}; @@ -16,7 +16,7 @@ use crate::ast::{GenericParam, GenericParamKind}; use crate::ast::GenericArg; use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind}; use crate::ast::{Label, Lifetime}; -use crate::ast::{Local, LocalSource}; +use crate::ast::Local; use crate::ast::MacStmtStyle; use crate::ast::{Mac, Mac_, MacDelimiter}; use crate::ast::{MutTy, Mutability}; @@ -51,7 +51,7 @@ use crate::parse::diagnostics::{Error, dummy_arg}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; -use syntax_pos::{Span, BytePos, DUMMY_SP, FileName, hygiene::CompilerDesugaringKind}; +use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; use log::debug; use std::borrow::Cow; @@ -1126,7 +1126,6 @@ impl<'a> Parser<'a> { IsAsync::Async { closure_id: ast::DUMMY_NODE_ID, return_impl_trait_id: ast::DUMMY_NODE_ID, - arguments: Vec::new(), } } else { IsAsync::NotAsync @@ -1185,12 +1184,12 @@ impl<'a> Parser<'a> { // trait item macro. (Ident::invalid(), ast::TraitItemKind::Macro(mac), ast::Generics::default()) } else { - let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?; + let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let mut decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| { + let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| { // This is somewhat dubious; We don't want to allow // argument names to be left off if there is a // definition... @@ -1199,7 +1198,6 @@ impl<'a> Parser<'a> { p.parse_arg_general(p.span.rust_2018(), true, false) })?; generics.where_clause = self.parse_where_clause()?; - self.construct_async_arguments(&mut asyncness, &mut decl); let sig = ast::MethodSig { header: FnHeader { @@ -1563,7 +1561,7 @@ impl<'a> Parser<'a> { } }; - Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal }) + Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID }) } /// Parses an argument in a lambda header (e.g., `|arg, arg|`). @@ -1581,8 +1579,7 @@ impl<'a> Parser<'a> { Ok(Arg { ty: t, pat, - id: ast::DUMMY_NODE_ID, - source: ast::ArgSource::Normal, + id: ast::DUMMY_NODE_ID }) } @@ -4213,7 +4210,6 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, span: lo.to(hi), attrs, - source: LocalSource::Normal, })) } @@ -5664,16 +5660,15 @@ impl<'a> Parser<'a> { /// Parses an item-position function declaration. fn parse_item_fn(&mut self, unsafety: Unsafety, - mut asyncness: Spanned, + asyncness: Spanned, constness: Spanned, abi: Abi) -> PResult<'a, ItemInfo> { let (ident, mut generics) = self.parse_fn_header()?; let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe; - let mut decl = self.parse_fn_decl(allow_c_variadic)?; + let decl = self.parse_fn_decl(allow_c_variadic)?; generics.where_clause = self.parse_where_clause()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - self.construct_async_arguments(&mut asyncness, &mut decl); let header = FnHeader { unsafety, asyncness, constness, abi }; Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs))) } @@ -5853,14 +5848,13 @@ impl<'a> Parser<'a> { Ok((Ident::invalid(), vec![], ast::Generics::default(), ast::ImplItemKind::Macro(mac))) } else { - let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?; + let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let mut decl = self.parse_fn_decl_with_self(|p| { + let decl = self.parse_fn_decl_with_self(|p| { p.parse_arg_general(true, true, false) })?; generics.where_clause = self.parse_where_clause()?; - self.construct_async_arguments(&mut asyncness, &mut decl); *at_end = true; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let header = ast::FnHeader { abi, unsafety, constness, asyncness }; @@ -7222,7 +7216,6 @@ impl<'a> Parser<'a> { respan(async_span, IsAsync::Async { closure_id: ast::DUMMY_NODE_ID, return_impl_trait_id: ast::DUMMY_NODE_ID, - arguments: Vec::new(), }), respan(fn_span, Constness::NotConst), Abi::Rust)?; @@ -7853,116 +7846,6 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ).emit(); } - - /// When lowering a `async fn` to the HIR, we need to move all of the arguments of the function - /// into the generated closure so that they are dropped when the future is polled and not when - /// it is created. - /// - /// The arguments of the function are replaced in HIR lowering with the arguments created by - /// this function and the statements created here are inserted at the top of the closure body. - fn construct_async_arguments(&mut self, asyncness: &mut Spanned, decl: &mut FnDecl) { - // FIXME(davidtwco): This function should really live in the HIR lowering but because - // the types constructed here need to be used in parts of resolve so that the correct - // locals are considered upvars, it is currently easier for it to live here in the parser, - // where it can be constructed once. - if let IsAsync::Async { ref mut arguments, .. } = asyncness.node { - for (index, input) in decl.inputs.iter_mut().enumerate() { - let id = ast::DUMMY_NODE_ID; - let span = input.pat.span; - let desugared_span = self.sess.source_map() - .mark_span_with_reason(CompilerDesugaringKind::Async, span, None); - - // Construct a name for our temporary argument. - let name = format!("__arg{}", index); - let ident = Ident::from_str(&name).gensym(); - - // Check if this is a ident pattern, if so, we can optimize and avoid adding a - // `let = __argN;` statement, instead just adding a `let = ;` - // statement. - let (binding_mode, ident, is_simple_pattern) = match input.pat.node { - PatKind::Ident(binding_mode @ BindingMode::ByValue(_), ident, _) => { - // Simple patterns like this don't have a generated argument, but they are - // moved into the closure with a statement, so any `mut` bindings on the - // argument will be unused. This binding mode can't be removed, because - // this would affect the input to procedural macros, but they can have - // their span marked as being the result of a compiler desugaring so - // that they aren't linted against. - input.pat.span = desugared_span; - - (binding_mode, ident, true) - } - _ => (BindingMode::ByValue(Mutability::Mutable), ident, false), - }; - - // Construct an argument representing `__argN: ` to replace the argument of the - // async function if it isn't a simple pattern. - let arg = if is_simple_pattern { - None - } else { - Some(Arg { - ty: input.ty.clone(), - id, - pat: P(Pat { - id, - node: PatKind::Ident( - BindingMode::ByValue(Mutability::Immutable), ident, None, - ), - span: desugared_span, - }), - source: ArgSource::AsyncFn(input.pat.clone()), - }) - }; - - // Construct a `let __argN = __argN;` statement to insert at the top of the - // async closure. This makes sure that the argument is captured by the closure and - // that the drop order is correct. - let move_local = Local { - pat: P(Pat { - id, - node: PatKind::Ident(binding_mode, ident, None), - span: desugared_span, - }), - // We explicitly do not specify the type for this statement. 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(Expr { - id, - node: ExprKind::Path(None, ast::Path { - span, - segments: vec![PathSegment { ident, id, args: None }], - }), - span, - attrs: ThinVec::new(), - })), - id, - span, - attrs: ThinVec::new(), - source: LocalSource::AsyncFn, - }; - - // Construct a `let = __argN;` statement to insert at the top of the - // async closure if this isn't a simple pattern. - let pat_stmt = if is_simple_pattern { - None - } else { - Some(Stmt { - id, - node: StmtKind::Local(P(Local { - pat: input.pat.clone(), - ..move_local.clone() - })), - span, - }) - }; - - let move_stmt = Stmt { id, node: StmtKind::Local(P(move_local)), span }; - arguments.push(AsyncArgument { ident, arg, pat_stmt, move_stmt }); - } - } - } } pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, handler: &errors::Handler) { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index cf546332c2c9d..b81dc53ef6836 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -357,7 +357,7 @@ pub fn vis_to_string(v: &ast::Visibility) -> String { } pub fn fun_to_string(decl: &ast::FnDecl, - header: &ast::FnHeader, + header: ast::FnHeader, name: ast::Ident, generics: &ast::Generics) -> String { @@ -1040,7 +1040,7 @@ impl<'a> State<'a> { match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { self.head("")?; - self.print_fn(decl, &ast::FnHeader::default(), + self.print_fn(decl, ast::FnHeader::default(), Some(item.ident), generics, &item.vis)?; self.end()?; // end head-ibox @@ -1170,7 +1170,7 @@ impl<'a> State<'a> { self.s.word(";")?; self.end()?; // end the outer cbox } - ast::ItemKind::Fn(ref decl, ref header, ref param_names, ref body) => { + ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => { self.head("")?; self.print_fn( decl, @@ -1522,7 +1522,7 @@ impl<'a> State<'a> { vis: &ast::Visibility) -> io::Result<()> { self.print_fn(&m.decl, - &m.header, + m.header, Some(ident), &generics, vis) @@ -2113,7 +2113,7 @@ impl<'a> State<'a> { self.bclose_(expr.span, INDENT_UNIT)?; } ast::ExprKind::Closure( - capture_clause, ref asyncness, movability, ref decl, ref body, _) => { + capture_clause, asyncness, movability, ref decl, ref body, _) => { self.print_movability(movability)?; self.print_asyncness(asyncness)?; self.print_capture_clause(capture_clause)?; @@ -2710,7 +2710,7 @@ impl<'a> State<'a> { pub fn print_fn(&mut self, decl: &ast::FnDecl, - header: &ast::FnHeader, + header: ast::FnHeader, name: Option, generics: &ast::Generics, vis: &ast::Visibility) -> io::Result<()> { @@ -2765,7 +2765,8 @@ impl<'a> State<'a> { } } - pub fn print_asyncness(&mut self, asyncness: &ast::IsAsync) -> io::Result<()> { + pub fn print_asyncness(&mut self, asyncness: ast::IsAsync) + -> io::Result<()> { if asyncness.is_async() { self.word_nbsp("async")?; } @@ -3037,7 +3038,7 @@ impl<'a> State<'a> { span: syntax_pos::DUMMY_SP, }; self.print_fn(decl, - &ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() }, + ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() }, name, &generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited))?; @@ -3100,7 +3101,7 @@ impl<'a> State<'a> { } pub fn print_fn_header_info(&mut self, - header: &ast::FnHeader, + header: ast::FnHeader, vis: &ast::Visibility) -> io::Result<()> { self.s.word(visibility_qualified(vis, ""))?; @@ -3109,7 +3110,7 @@ impl<'a> State<'a> { ast::Constness::Const => self.word_nbsp("const")? } - self.print_asyncness(&header.asyncness.node)?; + self.print_asyncness(header.asyncness.node)?; self.print_unsafety(header.unsafety)?; if header.abi != Abi::Rust { @@ -3158,7 +3159,7 @@ mod tests { assert_eq!( fun_to_string( &decl, - &ast::FnHeader { + ast::FnHeader { unsafety: ast::Unsafety::Normal, constness: source_map::dummy_spanned(ast::Constness::NotConst), asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync), diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 4b6893b242337..a21d2df416206 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -935,27 +935,6 @@ impl SourceMap { None } - - /// Reuses the span but adds information like the kind of the desugaring and features that are - /// allowed inside this span. - pub fn mark_span_with_reason( - &self, - reason: hygiene::CompilerDesugaringKind, - span: Span, - allow_internal_unstable: Option>, - ) -> Span { - let mark = Mark::fresh(Mark::root()); - mark.set_expn_info(ExpnInfo { - call_site: span, - def_site: Some(span), - format: CompilerDesugaring(reason), - allow_internal_unstable, - allow_internal_unsafe: false, - local_inner_macros: false, - edition: edition::Edition::from_session(), - }); - span.with_ctxt(SyntaxContext::empty().apply_mark(mark)) - } } impl SourceMapper for SourceMap { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4e096d68235b5..eb516b5c7c62f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -544,9 +544,6 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) { for argument in &function_declaration.inputs { visitor.visit_pat(&argument.pat); - if let ArgSource::AsyncFn(pat) = &argument.source { - visitor.visit_pat(pat); - } visitor.visit_ty(&argument.ty) } visitor.visit_fn_ret_ty(&function_declaration.output) diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index dec4c2dfc3b5e..44ddbb98809b4 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -129,7 +129,6 @@ fn stmt_let_undescore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P) -> ast id: ast::DUMMY_NODE_ID, span: sp, attrs: ThinVec::new(), - source: ast::LocalSource::Normal, }); ast::Stmt { id: ast::DUMMY_NODE_ID, diff --git a/src/test/ui/async-await/issues/issue-61187.rs b/src/test/ui/async-await/issues/issue-61187.rs new file mode 100644 index 0000000000000..8b939b43b8bd4 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-61187.rs @@ -0,0 +1,9 @@ +// edition:2018 +#![feature(async_await)] + +fn main() { +} + +async fn response(data: Vec) { + data.reverse(); //~ ERROR E0596 +} diff --git a/src/test/ui/async-await/issues/issue-61187.stderr b/src/test/ui/async-await/issues/issue-61187.stderr new file mode 100644 index 0000000000000..a03142263202e --- /dev/null +++ b/src/test/ui/async-await/issues/issue-61187.stderr @@ -0,0 +1,11 @@ +error[E0596]: cannot borrow `data` as mutable, as it is not declared as mutable + --> $DIR/issue-61187.rs:8:5 + | +LL | async fn response(data: Vec) { + | ---- help: consider changing this to be mutable: `mut data` +LL | data.reverse(); + | ^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index 654f4285f655f..ef9e7e39df0bc 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -30,7 +30,7 @@ error[E0106]: missing lifetime specifier LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^ expected lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_` or `y` + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` error: aborting due to 5 previous errors