summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_parse/src/parser/generics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src/parser/generics.rs')
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs61
1 files changed, 36 insertions, 25 deletions
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 8ba811715..8d0f168e0 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -1,4 +1,8 @@
-use crate::errors::{WhereClauseBeforeTupleStructBody, WhereClauseBeforeTupleStructBodySugg};
+use crate::errors::{
+ MultipleWhereClauses, UnexpectedDefaultValueForLifetimeInGenericParameters,
+ UnexpectedSelfInGenericParameters, WhereClauseBeforeTupleStructBody,
+ WhereClauseBeforeTupleStructBodySugg,
+};
use super::{ForceCollect, Parser, TrailingToken};
@@ -10,10 +14,11 @@ use rustc_ast::{
use rustc_errors::{Applicability, PResult};
use rustc_span::symbol::{kw, Ident};
use rustc_span::Span;
+use thin_vec::ThinVec;
enum PredicateOrStructBody {
Predicate(ast::WherePredicate),
- StructBody(Vec<ast::FieldDef>),
+ StructBody(ThinVec<ast::FieldDef>),
}
impl<'a> Parser<'a> {
@@ -117,8 +122,8 @@ impl<'a> Parser<'a> {
/// Parses a (possibly empty) list of lifetime and type parameters, possibly including
/// a trailing comma and erroneous trailing attributes.
- pub(super) fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
- let mut params = Vec::new();
+ pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> {
+ let mut params = ThinVec::new();
let mut done = false;
while !done {
let attrs = self.parse_outer_attributes()?;
@@ -127,12 +132,9 @@ impl<'a> Parser<'a> {
if this.eat_keyword_noexpect(kw::SelfUpper) {
// `Self` as a generic param is invalid. Here we emit the diagnostic and continue parsing
// as if `Self` never existed.
- this.struct_span_err(
- this.prev_token.span,
- "unexpected keyword `Self` in generic parameters",
- )
- .note("you cannot use `Self` as a generic parameter because it is reserved for associated items")
- .emit();
+ this.sess.emit_err(UnexpectedSelfInGenericParameters {
+ span: this.prev_token.span,
+ });
this.eat(&token::Comma);
}
@@ -145,6 +147,20 @@ impl<'a> Parser<'a> {
} else {
(None, Vec::new())
};
+
+ if this.check_noexpect(&token::Eq)
+ && this.look_ahead(1, |t| t.is_lifetime())
+ {
+ let lo = this.token.span;
+ // Parse `= 'lifetime`.
+ this.bump(); // `=`
+ this.bump(); // `'lifetime`
+ let span = lo.to(this.prev_token.span);
+ this.sess.emit_err(
+ UnexpectedDefaultValueForLifetimeInGenericParameters { span },
+ );
+ }
+
Some(ast::GenericParam {
ident: lifetime.ident,
id: lifetime.id,
@@ -236,13 +252,13 @@ impl<'a> Parser<'a> {
self.expect_gt()?;
(params, span_lo.to(self.prev_token.span))
} else {
- (vec![], self.prev_token.span.shrink_to_hi())
+ (ThinVec::new(), self.prev_token.span.shrink_to_hi())
};
Ok(ast::Generics {
params,
where_clause: WhereClause {
has_where_token: false,
- predicates: Vec::new(),
+ predicates: ThinVec::new(),
span: self.prev_token.span.shrink_to_hi(),
},
span,
@@ -262,17 +278,17 @@ impl<'a> Parser<'a> {
&mut self,
struct_name: Ident,
body_insertion_point: Span,
- ) -> PResult<'a, (WhereClause, Option<Vec<ast::FieldDef>>)> {
+ ) -> PResult<'a, (WhereClause, Option<ThinVec<ast::FieldDef>>)> {
self.parse_where_clause_common(Some((struct_name, body_insertion_point)))
}
fn parse_where_clause_common(
&mut self,
struct_: Option<(Ident, Span)>,
- ) -> PResult<'a, (WhereClause, Option<Vec<ast::FieldDef>>)> {
+ ) -> PResult<'a, (WhereClause, Option<ThinVec<ast::FieldDef>>)> {
let mut where_clause = WhereClause {
has_where_token: false,
- predicates: Vec::new(),
+ predicates: ThinVec::new(),
span: self.prev_token.span.shrink_to_hi(),
};
let mut tuple_struct_body = None;
@@ -329,16 +345,11 @@ impl<'a> Parser<'a> {
let ate_comma = self.eat(&token::Comma);
if self.eat_keyword_noexpect(kw::Where) {
- let msg = "cannot define duplicate `where` clauses on an item";
- let mut err = self.struct_span_err(self.token.span, msg);
- err.span_label(pred_lo, "previous `where` clause starts here");
- err.span_suggestion_verbose(
- prev_token.shrink_to_hi().to(self.prev_token.span),
- "consider joining the two `where` clauses into one",
- ",",
- Applicability::MaybeIncorrect,
- );
- err.emit();
+ self.sess.emit_err(MultipleWhereClauses {
+ span: self.token.span,
+ previous: pred_lo,
+ between: prev_token.shrink_to_hi().to(self.prev_token.span),
+ });
} else if !ate_comma {
break;
}