use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
use rustc_ast_pretty::pprust;
-use rustc_errors::{struct_span_err, Applicability, ErrorGuaranteed, PResult, StashKey};
+use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
use rustc_span::lev_distance::lev_distance;
use rustc_span::source_map::{self, Span};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::DUMMY_SP;
use std::convert::TryFrom;
use std::mem;
if end.is_doc_comment() {
err.span_label(end.span, "this doc comment doesn't document anything");
}
+ if end.meta_kind().is_some() {
+ if self.token.kind == TokenKind::Semi {
+ err.span_suggestion_verbose(
+ self.token.span,
+ "consider removing this semicolon",
+ String::new(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
if let [.., penultimate, _] = attrs {
err.span_label(start.span.to(penultimate.span), "other attributes here");
}
))
}
- /// Emits an error that the where clause at the end of a type alias is not
- /// allowed and suggests moving it.
- fn error_ty_alias_where(
- &self,
- before_where_clause_present: bool,
- before_where_clause_span: Span,
- after_predicates: &[WherePredicate],
- after_where_clause_span: Span,
- ) -> ErrorGuaranteed {
- let mut err =
- self.struct_span_err(after_where_clause_span, "where clause not allowed here");
- if !after_predicates.is_empty() {
- let mut state = crate::pprust::State::new();
- if !before_where_clause_present {
- state.space();
- state.word_space("where");
- } else {
- state.word_space(",");
- }
- let mut first = true;
- for p in after_predicates.iter() {
- if !first {
- state.word_space(",");
- }
- first = false;
- state.print_where_predicate(p);
- }
- let suggestion = state.s.eof();
- err.span_suggestion(
- before_where_clause_span.shrink_to_hi(),
- "move it here",
- suggestion,
- Applicability::MachineApplicable,
- );
- }
- err.emit()
- }
-
/// Parses a `type` alias with the following grammar:
/// ```
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
// Parse optional colon and param bounds.
let bounds =
if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
-
- generics.where_clause = self.parse_where_clause()?;
+ let before_where_clause = self.parse_where_clause()?;
let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
- if self.token.is_keyword(kw::Where) {
- let after_where_clause = self.parse_where_clause()?;
+ let after_where_clause = self.parse_where_clause()?;
- self.error_ty_alias_where(
- generics.where_clause.has_where_token,
- generics.where_clause.span,
- &after_where_clause.predicates,
- after_where_clause.span,
- );
-
- generics.where_clause.predicates.extend(after_where_clause.predicates.into_iter());
- }
+ let where_clauses = (
+ TyAliasWhereClause(before_where_clause.has_where_token, before_where_clause.span),
+ TyAliasWhereClause(after_where_clause.has_where_token, after_where_clause.span),
+ );
+ let where_predicates_split = before_where_clause.predicates.len();
+ let mut predicates = before_where_clause.predicates;
+ predicates.extend(after_where_clause.predicates.into_iter());
+ let where_clause = WhereClause {
+ has_where_token: before_where_clause.has_where_token
+ || after_where_clause.has_where_token,
+ predicates,
+ span: DUMMY_SP,
+ };
+ generics.where_clause = where_clause;
self.expect_semi()?;
- Ok((ident, ItemKind::TyAlias(Box::new(TyAlias { defaultness, generics, bounds, ty }))))
+ Ok((
+ ident,
+ ItemKind::TyAlias(Box::new(TyAlias {
+ defaultness,
+ generics,
+ where_clauses,
+ where_predicates_split,
+ bounds,
+ ty,
+ })),
+ ))
}
/// Parses a `UseTree`.
let name = self.parse_field_ident(adt_ty, lo)?;
self.expect_field_ty_separator()?;
let ty = self.parse_ty()?;
+ if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
+ self.struct_span_err(self.token.span, "found single colon in a struct field type path")
+ .span_suggestion_verbose(
+ self.token.span,
+ "write a path separator here",
+ "::".to_string(),
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ }
if self.token.kind == token::Eq {
self.bump();
let const_expr = self.parse_anon_const_expr()?;