diff options
| author | n-salim <53019816+n-salim@users.noreply.github.com> | 2019-09-23 14:12:26 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-23 14:12:26 -0700 |
| commit | cd88dae21174f37aa47a45e4b848c4a5ececf19e (patch) | |
| tree | 196ef2334e2f7787737af02f2e78ed53c10fb5a8 /src/libsyntax/parse | |
| parent | 494d83c89279a955dfb559ded5d5ac2ac06fc255 (diff) | |
| parent | 66bf391c3aabfc77f5f7139fc9e6944f995d574e (diff) | |
| download | rust-cd88dae21174f37aa47a45e4b848c4a5ececf19e.tar.gz rust-cd88dae21174f37aa47a45e4b848c4a5ececf19e.zip | |
Merge pull request #26 from rust-lang/master
Sync to rust-lang/rust master
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/parse/diagnostics.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/tests.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/expr.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/generics.rs | 99 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/pat.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/path.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/stmt.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser/ty.rs | 6 |
11 files changed, 95 insertions, 79 deletions
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 9aa1ec0b14f..cf6151d17b1 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -19,13 +19,6 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \ permitted in this context"; impl<'a> Parser<'a> { - crate fn parse_param_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> { - let attrs = self.parse_outer_attributes()?; - self.sess.gated_spans.param_attrs.borrow_mut() - .extend(attrs.iter().map(|a| a.span)); - Ok(attrs) - } - /// Parses attributes that appear before an item. crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> { let mut attrs: Vec<ast::Attribute> = Vec::new(); @@ -309,14 +302,14 @@ impl<'a> Parser<'a> { Ok(lit) => { return Ok(ast::NestedMetaItem::Literal(lit)) } - Err(ref mut err) => self.diagnostic().cancel(err) + Err(ref mut err) => err.cancel(), } match self.parse_meta_item() { Ok(mi) => { return Ok(ast::NestedMetaItem::MetaItem(mi)) } - Err(ref mut err) => self.diagnostic().cancel(err) + Err(ref mut err) => err.cancel(), } let found = self.this_token_to_string(); diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index b74f2492c35..59de5f14123 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -11,7 +11,7 @@ use crate::ptr::P; use crate::symbol::{kw, sym}; use crate::ThinVec; use crate::util::parser::AssocOp; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise}; use rustc_data_structures::fx::FxHashSet; use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError}; use log::{debug, trace}; @@ -197,10 +197,6 @@ impl<'a> Parser<'a> { self.sess.span_diagnostic.span_bug(sp, m) } - crate fn cancel(&self, err: &mut DiagnosticBuilder<'_>) { - self.sess.span_diagnostic.cancel(err) - } - crate fn diagnostic(&self) -> &'a errors::Handler { &self.sess.span_diagnostic } @@ -426,15 +422,13 @@ impl<'a> Parser<'a> { /// Eats and discards tokens until one of `kets` is encountered. Respects token trees, /// passes through any errors encountered. Used for error recovery. crate fn eat_to_tokens(&mut self, kets: &[&TokenKind]) { - let handler = self.diagnostic(); - if let Err(ref mut err) = self.parse_seq_to_before_tokens( kets, SeqSep::none(), TokenExpectType::Expect, |p| Ok(p.parse_token_tree()), ) { - handler.cancel(err); + err.cancel(); } } @@ -532,15 +526,15 @@ impl<'a> Parser<'a> { self.eat_to_tokens(&[&end]); let span = lo.until(self.token.span); - let plural = number_of_gt > 1 || number_of_shr >= 1; + let total_num_of_gt = number_of_gt + number_of_shr * 2; self.diagnostic() .struct_span_err( span, - &format!("unmatched angle bracket{}", if plural { "s" } else { "" }), + &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)), ) .span_suggestion( span, - &format!("remove extra angle bracket{}", if plural { "s" } else { "" }), + &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)), String::new(), Applicability::MachineApplicable, ) diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs index c1ec41902e2..de301b1fc49 100644 --- a/src/libsyntax/parse/lexer/tests.rs +++ b/src/libsyntax/parse/lexer/tests.rs @@ -18,6 +18,7 @@ fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess { false, false, None, + false, ); ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm) } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 2441a027f99..fa4c1043122 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -49,8 +49,6 @@ static_assert_size!(PResult<'_, bool>, 16); /// used and should be feature gated accordingly in `check_crate`. #[derive(Default)] pub struct GatedSpans { - /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`. - pub param_attrs: Lock<Vec<Span>>, /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`. pub let_chains: Lock<Vec<Span>>, /// Spans collected for gating `async_closure`, e.g. `async || ..`. @@ -306,7 +304,7 @@ fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, Err(d) => { - DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit(); + sess.span_diagnostic.emit_diagnostic(&d); FatalError.raise(); } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fcebfa29962..b2b6504919e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -979,7 +979,7 @@ impl<'a> Parser<'a> { is_name_required: impl Fn(&token::Token) -> bool, ) -> PResult<'a, Param> { let lo = self.token.span; - let attrs = self.parse_param_attributes()?; + let attrs = self.parse_outer_attributes()?; if let Some(mut param) = self.parse_self_param()? { param.attrs = attrs.into(); return self.recover_bad_self_param(param, is_trait_item); @@ -1362,7 +1362,7 @@ impl<'a> Parser<'a> { /// Returns the parsed optional self parameter with attributes and whether a self /// shortcut was used. fn parse_self_parameter_with_attrs(&mut self) -> PResult<'a, Option<Param>> { - let attrs = self.parse_param_attributes()?; + let attrs = self.parse_outer_attributes()?; let param_opt = self.parse_self_param()?; Ok(param_opt.map(|mut param| { param.attrs = attrs.into(); diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 31b28443abb..d0c865a7b8e 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -66,6 +66,10 @@ pub(super) enum LhsExpr { } impl From<Option<ThinVec<Attribute>>> for LhsExpr { + /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)` + /// and `None` into `LhsExpr::NotYetParsed`. + /// + /// This conversion does not allocate. fn from(o: Option<ThinVec<Attribute>>) -> Self { if let Some(attrs) = o { LhsExpr::AttributesParsed(attrs) @@ -76,6 +80,9 @@ impl From<Option<ThinVec<Attribute>>> for LhsExpr { } impl From<P<Expr>> for LhsExpr { + /// Converts the `expr: P<Expr>` into `LhsExpr::AlreadyParsed(expr)`. + /// + /// This conversion does not allocate. fn from(expr: P<Expr>) -> Self { LhsExpr::AlreadyParsed(expr) } @@ -770,7 +777,7 @@ impl<'a> Parser<'a> { ex = ExprKind::Lit(literal); } Err(mut err) => { - self.cancel(&mut err); + err.cancel(); return Err(self.expected_expression_found()); } } @@ -1176,7 +1183,7 @@ impl<'a> Parser<'a> { /// Parses a parameter in a closure header (e.g., `|arg, arg|`). fn parse_fn_block_param(&mut self) -> PResult<'a, Param> { let lo = self.token.span; - let attrs = self.parse_param_attributes()?; + let attrs = self.parse_outer_attributes()?; let pat = self.parse_pat(PARAM_EXPECTED)?; let t = if self.eat(&token::Colon) { self.parse_ty()? diff --git a/src/libsyntax/parse/parser/generics.rs b/src/libsyntax/parse/parser/generics.rs index 3e6118ad86f..2ecd9cca3c6 100644 --- a/src/libsyntax/parse/parser/generics.rs +++ b/src/libsyntax/parse/parser/generics.rs @@ -100,13 +100,31 @@ impl<'a> Parser<'a> { } else if self.check_ident() { // Parse type parameter. params.push(self.parse_ty_param(attrs)?); + } else if self.token.can_begin_type() { + // Trying to write an associated type bound? (#26271) + let snapshot = self.clone(); + match self.parse_ty_where_predicate() { + Ok(where_predicate) => { + self.struct_span_err( + where_predicate.span(), + "bounds on associated types do not belong here", + ) + .span_label(where_predicate.span(), "belongs in `where` clause") + .emit(); + } + Err(mut err) => { + err.cancel(); + std::mem::replace(self, snapshot); + break + } + } } else { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { if !params.is_empty() { self.struct_span_err( attrs[0].span, - &format!("trailing attribute after generic parameter"), + "trailing attribute after generic parameter", ) .span_label(attrs[0].span, "attributes must go before parameters") .emit(); @@ -202,43 +220,7 @@ impl<'a> Parser<'a> { } )); } else if self.check_type() { - // Parse optional `for<'a, 'b>`. - // This `for` is parsed greedily and applies to the whole predicate, - // the bounded type can have its own `for` applying only to it. - // Examples: - // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>` - // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>` - // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; - - // Parse type with mandatory colon and (possibly empty) bounds, - // or with mandatory equality sign and the second type. - let ty = self.parse_ty()?; - if self.eat(&token::Colon) { - let bounds = self.parse_generic_bounds(Some(self.prev_span))?; - where_clause.predicates.push(ast::WherePredicate::BoundPredicate( - ast::WhereBoundPredicate { - span: lo.to(self.prev_span), - bound_generic_params: lifetime_defs, - bounded_ty: ty, - bounds, - } - )); - // FIXME: Decide what should be used here, `=` or `==`. - // FIXME: We are just dropping the binders in lifetime_defs on the floor here. - } else if self.eat(&token::Eq) || self.eat(&token::EqEq) { - let rhs_ty = self.parse_ty()?; - where_clause.predicates.push(ast::WherePredicate::EqPredicate( - ast::WhereEqPredicate { - span: lo.to(self.prev_span), - lhs_ty: ty, - rhs_ty, - id: ast::DUMMY_NODE_ID, - } - )); - } else { - return self.unexpected(); - } + where_clause.predicates.push(self.parse_ty_where_predicate()?); } else { break } @@ -252,6 +234,47 @@ impl<'a> Parser<'a> { Ok(where_clause) } + fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> { + let lo = self.token.span; + // Parse optional `for<'a, 'b>`. + // This `for` is parsed greedily and applies to the whole predicate, + // the bounded type can have its own `for` applying only to it. + // Examples: + // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>` + // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>` + // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` + let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + + // Parse type with mandatory colon and (possibly empty) bounds, + // or with mandatory equality sign and the second type. + let ty = self.parse_ty()?; + if self.eat(&token::Colon) { + let bounds = self.parse_generic_bounds(Some(self.prev_span))?; + Ok(ast::WherePredicate::BoundPredicate( + ast::WhereBoundPredicate { + span: lo.to(self.prev_span), + bound_generic_params: lifetime_defs, + bounded_ty: ty, + bounds, + } + )) + // FIXME: Decide what should be used here, `=` or `==`. + // FIXME: We are just dropping the binders in lifetime_defs on the floor here. + } else if self.eat(&token::Eq) || self.eat(&token::EqEq) { + let rhs_ty = self.parse_ty()?; + Ok(ast::WherePredicate::EqPredicate( + ast::WhereEqPredicate { + span: lo.to(self.prev_span), + lhs_ty: ty, + rhs_ty, + id: ast::DUMMY_NODE_ID, + } + )) + } else { + self.unexpected() + } + } + pub(super) fn choose_generics_over_qpath(&self) -> bool { // There's an ambiguity between generic parameters and qualified paths in impls. // If we see `<` it may start both, so we have to inspect some following tokens. diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index 08ee3a6bd86..3c624959ead 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -537,7 +537,7 @@ impl<'a> Parser<'a> { mut err: DiagnosticBuilder<'a>, expected: Expected, ) -> PResult<'a, P<Pat>> { - self.cancel(&mut err); + err.cancel(); let expected = expected.unwrap_or("pattern"); let msg = format!("expected {}, found {}", expected, self.this_token_descr()); diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs index d4b13cc2e01..87839f8c70e 100644 --- a/src/libsyntax/parse/parser/path.rs +++ b/src/libsyntax/parse/parser/path.rs @@ -9,7 +9,7 @@ use crate::symbol::kw; use std::mem; use log::debug; -use errors::{Applicability}; +use errors::{Applicability, pluralise}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -129,10 +129,11 @@ impl<'a> Parser<'a> { self.parse_path(style) } - crate fn parse_path_segments(&mut self, - segments: &mut Vec<PathSegment>, - style: PathStyle) - -> PResult<'a, ()> { + crate fn parse_path_segments( + &mut self, + segments: &mut Vec<PathSegment>, + style: PathStyle, + ) -> PResult<'a, ()> { loop { let segment = self.parse_path_segment(style)?; if style == PathStyle::Expr { @@ -201,7 +202,7 @@ impl<'a> Parser<'a> { } else { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; - let span = lo.to(self.prev_span); + let span = ident.span.to(self.prev_span); let output = if self.eat(&token::RArrow) { Some(self.parse_ty_common(false, false, false)?) } else { @@ -347,20 +348,19 @@ impl<'a> Parser<'a> { let span = lo.with_hi( lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count) ); - let plural = snapshot.unmatched_angle_bracket_count > 1; self.diagnostic() .struct_span_err( span, &format!( "unmatched angle bracket{}", - if plural { "s" } else { "" } + pluralise!(snapshot.unmatched_angle_bracket_count) ), ) .span_suggestion( span, &format!( "remove extra angle bracket{}", - if plural { "s" } else { "" } + pluralise!(snapshot.unmatched_angle_bracket_count) ), String::new(), Applicability::MachineApplicable, diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs index 04bd61a4cfb..02da56f6e35 100644 --- a/src/libsyntax/parse/parser/stmt.rs +++ b/src/libsyntax/parse/parser/stmt.rs @@ -361,7 +361,7 @@ impl<'a> Parser<'a> { } Err(mut e) => { self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); - self.cancel(&mut e); + e.cancel(); } _ => () } diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs index 465e31ac57e..5697edd8e48 100644 --- a/src/libsyntax/parse/parser/ty.rs +++ b/src/libsyntax/parse/parser/ty.rs @@ -11,7 +11,7 @@ use crate::symbol::{kw}; use rustc_target::spec::abi::Abi; -use errors::{Applicability}; +use errors::{Applicability, pluralise}; /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`, /// `IDENT<<u8 as Trait>::AssocTy>`. @@ -397,7 +397,7 @@ impl<'a> Parser<'a> { } if !negative_bounds.is_empty() || was_negative { - let plural = negative_bounds.len() > 1; + let negative_bounds_len = negative_bounds.len(); let last_span = negative_bounds.last().map(|sp| *sp); let mut err = self.struct_span_err( negative_bounds, @@ -420,7 +420,7 @@ impl<'a> Parser<'a> { } err.span_suggestion_hidden( bound_list, - &format!("remove the trait bound{}", if plural { "s" } else { "" }), + &format!("remove the trait bound{}", pluralise!(negative_bounds_len)), new_bound_list, Applicability::MachineApplicable, ); |
