From ad0d3b5d4064cfd9013c498299a53b3f1586553e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 May 2019 18:19:48 -0700 Subject: [PATCH] Move code from `parser` to `diagnostics` --- src/libsyntax/parse/diagnostics.rs | 41 +++++++++++++++++++++++++++--- src/libsyntax/parse/parser.rs | 35 ++----------------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index b6f26c73a70..138b2ccfe35 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -1,7 +1,6 @@ -use crate::ast; use crate::ast::{ - BlockCheckMode, BinOpKind, Expr, ExprKind, Item, ItemKind, Pat, PatKind, PathSegment, QSelf, - Ty, TyKind, VariantData, Ident, + self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind, + Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData, }; use crate::parse::{SeqSep, token, PResult, Parser}; use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType}; @@ -12,9 +11,25 @@ use crate::ThinVec; use crate::util::parser::AssocOp; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use rustc_data_structures::fx::FxHashSet; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use log::{debug, trace}; +/// Creates a placeholder argument. +crate fn dummy_arg(ident: Ident) -> Arg { + let pat = P(Pat { + id: ast::DUMMY_NODE_ID, + node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None), + span: ident.span, + }); + let ty = Ty { + node: TyKind::Err, + span: ident.span, + id: ast::DUMMY_NODE_ID + }; + Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal } +} + pub enum Error { FileNotFoundForModule { mod_name: String, @@ -1217,4 +1232,24 @@ pub fn unexpected_try_recover( err.span_label(span, "expected expression"); err } + + /// Replace duplicated recovered arguments with `_` pattern to avoid unecessary errors. + crate fn deduplicate_recovered_arg_names(&self, fn_inputs: &mut Vec) { + let mut seen_inputs = FxHashSet::default(); + for input in fn_inputs.iter_mut() { + let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = ( + &input.pat.node, &input.ty.node, + ) { + Some(*ident) + } else { + None + }; + if let Some(ident) = opt_ident { + if seen_inputs.contains(&ident) { + input.pat.node = PatKind::Wild; + } + seen_inputs.insert(ident); + } + } + } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3bb34d0402d..659058ffcf3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -47,11 +47,10 @@ use crate::ThinVec; use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use crate::symbol::{kw, sym, Symbol}; -use crate::parse::diagnostics::Error; +use crate::parse::diagnostics::{Error, dummy_arg}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; -use rustc_data_structures::fx::FxHashSet; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName, hygiene::CompilerDesugaringKind}; use log::debug; @@ -452,21 +451,6 @@ fn from(expr: P) -> Self { } } -/// Creates a placeholder argument. -fn dummy_arg(ident: Ident) -> Arg { - let pat = P(Pat { - id: ast::DUMMY_NODE_ID, - node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None), - span: ident.span, - }); - let ty = Ty { - node: TyKind::Err, - span: ident.span, - id: ast::DUMMY_NODE_ID - }; - Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal } -} - #[derive(Copy, Clone, Debug)] crate enum TokenExpectType { Expect, @@ -5617,22 +5601,7 @@ fn parse_fn_decl_with_self(&mut self, parse_arg_fn: F) -> PResult<'a, P