diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh
index e05246201dd0c..4c03419894e7c 100644
--- a/src/ci/docker/scripts/sccache.sh
+++ b/src/ci/docker/scripts/sccache.sh
@@ -1,5 +1,3 @@
-# ignore-tidy-linelength
-
set -ex
curl -fo /usr/local/bin/sccache \
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 7a5511ee1dc8b..89dfa0d3e4850 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2214,7 +2214,7 @@ impl str {
/// modified in a way that it remains valid UTF-8.
///
/// [`u8`]: primitive.u8.html
- #[unstable(feature = "str_as_mut_ptr", issue = "58215")]
+ #[stable(feature = "str_as_mut_ptr", since = "1.36.0")]
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self as *mut str as *mut u8
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index f6917c45d57e8..7f68b35d014cb 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
#![allow(non_snake_case)]
// Error messages for EXXXX errors.
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index ba67593ce968a..fdca3230904a8 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
// ignore-tidy-filelength
#![allow(non_snake_case)]
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
new file mode 100644
index 0000000000000..32e1ee94f0dfb
--- /dev/null
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -0,0 +1,226 @@
+use crate::ast;
+use crate::ast::{Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
+use crate::parse::parser::PathStyle;
+use crate::parse::token;
+use crate::parse::PResult;
+use crate::parse::Parser;
+use crate::print::pprust;
+use crate::ptr::P;
+use crate::ThinVec;
+use errors::Applicability;
+use syntax_pos::Span;
+
+pub trait RecoverQPath: Sized + 'static {
+ const PATH_STYLE: PathStyle = PathStyle::Expr;
+ fn to_ty(&self) -> Option
>;
+ fn recovered(qself: Option, path: ast::Path) -> Self;
+}
+
+impl RecoverQPath for Ty {
+ const PATH_STYLE: PathStyle = PathStyle::Type;
+ fn to_ty(&self) -> Option> {
+ Some(P(self.clone()))
+ }
+ fn recovered(qself: Option, path: ast::Path) -> Self {
+ Self {
+ span: path.span,
+ node: TyKind::Path(qself, path),
+ id: ast::DUMMY_NODE_ID,
+ }
+ }
+}
+
+impl RecoverQPath for Pat {
+ fn to_ty(&self) -> Option> {
+ self.to_ty()
+ }
+ fn recovered(qself: Option, path: ast::Path) -> Self {
+ Self {
+ span: path.span,
+ node: PatKind::Path(qself, path),
+ id: ast::DUMMY_NODE_ID,
+ }
+ }
+}
+
+impl RecoverQPath for Expr {
+ fn to_ty(&self) -> Option> {
+ self.to_ty()
+ }
+ fn recovered(qself: Option, path: ast::Path) -> Self {
+ Self {
+ span: path.span,
+ node: ExprKind::Path(qself, path),
+ attrs: ThinVec::new(),
+ id: ast::DUMMY_NODE_ID,
+ }
+ }
+}
+
+impl<'a> Parser<'a> {
+ crate fn maybe_report_ambiguous_plus(
+ &mut self,
+ allow_plus: bool,
+ impl_dyn_multi: bool,
+ ty: &Ty,
+ ) {
+ if !allow_plus && impl_dyn_multi {
+ let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
+ self.struct_span_err(ty.span, "ambiguous `+` in a type")
+ .span_suggestion(
+ ty.span,
+ "use parentheses to disambiguate",
+ sum_with_parens,
+ Applicability::MachineApplicable,
+ )
+ .emit();
+ }
+ }
+
+ crate fn maybe_recover_from_bad_type_plus(
+ &mut self,
+ allow_plus: bool,
+ ty: &Ty,
+ ) -> PResult<'a, ()> {
+ // Do not add `+` to expected tokens.
+ if !allow_plus || !self.token.is_like_plus() {
+ return Ok(());
+ }
+
+ self.bump(); // `+`
+ let bounds = self.parse_generic_bounds(None)?;
+ let sum_span = ty.span.to(self.prev_span);
+
+ let mut err = struct_span_err!(
+ self.sess.span_diagnostic,
+ sum_span,
+ E0178,
+ "expected a path on the left-hand side of `+`, not `{}`",
+ pprust::ty_to_string(ty)
+ );
+
+ match ty.node {
+ TyKind::Rptr(ref lifetime, ref mut_ty) => {
+ let sum_with_parens = pprust::to_string(|s| {
+ use crate::print::pprust::PrintState;
+
+ s.s.word("&")?;
+ s.print_opt_lifetime(lifetime)?;
+ s.print_mutability(mut_ty.mutbl)?;
+ s.popen()?;
+ s.print_type(&mut_ty.ty)?;
+ s.print_type_bounds(" +", &bounds)?;
+ s.pclose()
+ });
+ err.span_suggestion(
+ sum_span,
+ "try adding parentheses",
+ sum_with_parens,
+ Applicability::MachineApplicable,
+ );
+ }
+ TyKind::Ptr(..) | TyKind::BareFn(..) => {
+ err.span_label(sum_span, "perhaps you forgot parentheses?");
+ }
+ _ => {
+ err.span_label(sum_span, "expected a path");
+ }
+ }
+ err.emit();
+ Ok(())
+ }
+
+ /// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
+ /// Attempt to convert the base expression/pattern/type into a type, parse the `::AssocItem`
+ /// tail, and combine them into a `::AssocItem` expression/pattern/type.
+ crate fn maybe_recover_from_bad_qpath(
+ &mut self,
+ base: P,
+ allow_recovery: bool,
+ ) -> PResult<'a, P> {
+ // Do not add `::` to expected tokens.
+ if allow_recovery && self.token == token::ModSep {
+ if let Some(ty) = base.to_ty() {
+ return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
+ }
+ }
+ Ok(base)
+ }
+
+ /// Given an already parsed `Ty` parse the `::AssocItem` tail and
+ /// combine them into a `::AssocItem` expression/pattern/type.
+ crate fn maybe_recover_from_bad_qpath_stage_2(
+ &mut self,
+ ty_span: Span,
+ ty: P,
+ ) -> PResult<'a, P> {
+ self.expect(&token::ModSep)?;
+
+ let mut path = ast::Path {
+ segments: Vec::new(),
+ span: syntax_pos::DUMMY_SP,
+ };
+ self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?;
+ path.span = ty_span.to(self.prev_span);
+
+ let ty_str = self
+ .sess
+ .source_map()
+ .span_to_snippet(ty_span)
+ .unwrap_or_else(|_| pprust::ty_to_string(&ty));
+ self.diagnostic()
+ .struct_span_err(path.span, "missing angle brackets in associated item path")
+ .span_suggestion(
+ // this is a best-effort recovery
+ path.span,
+ "try",
+ format!("<{}>::{}", ty_str, path),
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+
+ let path_span = ty_span.shrink_to_hi(); // use an empty path since `position` == 0
+ Ok(P(T::recovered(
+ Some(QSelf {
+ ty,
+ path_span,
+ position: 0,
+ }),
+ path,
+ )))
+ }
+
+ crate fn maybe_consume_incorrect_semicolon(&mut self, items: &[P- ]) -> bool {
+ if self.eat(&token::Semi) {
+ let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`");
+ err.span_suggestion_short(
+ self.prev_span,
+ "remove this semicolon",
+ String::new(),
+ Applicability::MachineApplicable,
+ );
+ if !items.is_empty() {
+ let previous_item = &items[items.len() - 1];
+ let previous_item_kind_name = match previous_item.node {
+ // say "braced struct" because tuple-structs and
+ // braceless-empty-struct declarations do take a semicolon
+ ItemKind::Struct(..) => Some("braced struct"),
+ ItemKind::Enum(..) => Some("enum"),
+ ItemKind::Trait(..) => Some("trait"),
+ ItemKind::Union(..) => Some("union"),
+ _ => None,
+ };
+ if let Some(name) = previous_item_kind_name {
+ err.help(&format!(
+ "{} declarations are not followed by a semicolon",
+ name
+ ));
+ }
+ }
+ err.emit();
+ true
+ } else {
+ false
+ }
+ }
+}
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 371e8fe5cf66f..608d00f5548f7 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -30,6 +30,7 @@ pub mod parser;
pub mod lexer;
pub mod token;
pub mod attr;
+pub mod diagnostics;
pub mod classify;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8efe84cdf016f..9d863612657fa 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -189,41 +189,6 @@ enum PrevTokenKind {
Other,
}
-trait RecoverQPath: Sized + 'static {
- const PATH_STYLE: PathStyle = PathStyle::Expr;
- fn to_ty(&self) -> Option
>;
- fn recovered(qself: Option, path: ast::Path) -> Self;
-}
-
-impl RecoverQPath for Ty {
- const PATH_STYLE: PathStyle = PathStyle::Type;
- fn to_ty(&self) -> Option> {
- Some(P(self.clone()))
- }
- fn recovered(qself: Option, path: ast::Path) -> Self {
- Self { span: path.span, node: TyKind::Path(qself, path), id: ast::DUMMY_NODE_ID }
- }
-}
-
-impl RecoverQPath for Pat {
- fn to_ty(&self) -> Option> {
- self.to_ty()
- }
- fn recovered(qself: Option, path: ast::Path) -> Self {
- Self { span: path.span, node: PatKind::Path(qself, path), id: ast::DUMMY_NODE_ID }
- }
-}
-
-impl RecoverQPath for Expr {
- fn to_ty(&self) -> Option> {
- self.to_ty()
- }
- fn recovered(qself: Option, path: ast::Path) -> Self {
- Self { span: path.span, node: ExprKind::Path(qself, path),
- attrs: ThinVec::new(), id: ast::DUMMY_NODE_ID }
- }
-}
-
/* ident is handled by common.rs */
#[derive(Clone)]
@@ -1479,7 +1444,7 @@ impl<'a> Parser<'a> {
fn span_err>(&self, sp: S, m: &str) {
self.sess.span_diagnostic.span_err(sp, m)
}
- fn struct_span_err>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
+ crate fn struct_span_err>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
self.sess.span_diagnostic.struct_span_err(sp, m)
}
fn struct_span_warn>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
@@ -1882,99 +1847,6 @@ impl<'a> Parser<'a> {
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
}
- fn maybe_report_ambiguous_plus(&mut self, allow_plus: bool, impl_dyn_multi: bool, ty: &Ty) {
- if !allow_plus && impl_dyn_multi {
- let sum_with_parens = format!("({})", pprust::ty_to_string(&ty));
- self.struct_span_err(ty.span, "ambiguous `+` in a type")
- .span_suggestion(
- ty.span,
- "use parentheses to disambiguate",
- sum_with_parens,
- Applicability::MachineApplicable
- ).emit();
- }
- }
-
- fn maybe_recover_from_bad_type_plus(&mut self, allow_plus: bool, ty: &Ty) -> PResult<'a, ()> {
- // Do not add `+` to expected tokens.
- if !allow_plus || !self.token.is_like_plus() {
- return Ok(())
- }
-
- self.bump(); // `+`
- let bounds = self.parse_generic_bounds(None)?;
- let sum_span = ty.span.to(self.prev_span);
-
- let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178,
- "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(ty));
-
- match ty.node {
- TyKind::Rptr(ref lifetime, ref mut_ty) => {
- let sum_with_parens = pprust::to_string(|s| {
- use crate::print::pprust::PrintState;
-
- s.s.word("&")?;
- s.print_opt_lifetime(lifetime)?;
- s.print_mutability(mut_ty.mutbl)?;
- s.popen()?;
- s.print_type(&mut_ty.ty)?;
- s.print_type_bounds(" +", &bounds)?;
- s.pclose()
- });
- err.span_suggestion(
- sum_span,
- "try adding parentheses",
- sum_with_parens,
- Applicability::MachineApplicable
- );
- }
- TyKind::Ptr(..) | TyKind::BareFn(..) => {
- err.span_label(sum_span, "perhaps you forgot parentheses?");
- }
- _ => {
- err.span_label(sum_span, "expected a path");
- },
- }
- err.emit();
- Ok(())
- }
-
- /// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
- /// Attempt to convert the base expression/pattern/type into a type, parse the `::AssocItem`
- /// tail, and combine them into a `::AssocItem` expression/pattern/type.
- fn maybe_recover_from_bad_qpath(&mut self, base: P, allow_recovery: bool)
- -> PResult<'a, P> {
- // Do not add `::` to expected tokens.
- if allow_recovery && self.token == token::ModSep {
- if let Some(ty) = base.to_ty() {
- return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
- }
- }
- Ok(base)
- }
-
- /// Given an already parsed `Ty` parse the `::AssocItem` tail and
- /// combine them into a `::AssocItem` expression/pattern/type.
- fn maybe_recover_from_bad_qpath_stage_2(&mut self, ty_span: Span, ty: P)
- -> PResult<'a, P> {
- self.expect(&token::ModSep)?;
-
- let mut path = ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP };
- self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?;
- path.span = ty_span.to(self.prev_span);
-
- let ty_str = self.sess.source_map().span_to_snippet(ty_span)
- .unwrap_or_else(|_| pprust::ty_to_string(&ty));
- self.diagnostic()
- .struct_span_err(path.span, "missing angle brackets in associated item path")
- .span_suggestion( // this is a best-effort recovery
- path.span, "try", format!("<{}>::{}", ty_str, path), Applicability::MaybeIncorrect
- ).emit();
-
- let path_span = ty_span.shrink_to_hi(); // use an empty path since `position` == 0
- Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
- }
-
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None };
let mutbl = self.parse_mutability();
@@ -2410,7 +2282,7 @@ impl<'a> Parser<'a> {
self.parse_path(style)
}
- fn parse_path_segments(&mut self,
+ crate fn parse_path_segments(&mut self,
segments: &mut Vec,
style: PathStyle)
-> PResult<'a, ()> {
@@ -5815,7 +5687,7 @@ impl<'a> Parser<'a> {
return Ok(bounds);
}
- fn parse_generic_bounds(&mut self, colon_span: Option) -> PResult<'a, GenericBounds> {
+ crate fn parse_generic_bounds(&mut self, colon_span: Option) -> PResult<'a, GenericBounds> {
self.parse_generic_bounds_common(true, colon_span)
}
@@ -7352,37 +7224,6 @@ impl<'a> Parser<'a> {
}
}
- fn maybe_consume_incorrect_semicolon(&mut self, items: &[P- ]) -> bool {
- if self.eat(&token::Semi) {
- let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`");
- err.span_suggestion_short(
- self.prev_span,
- "remove this semicolon",
- String::new(),
- Applicability::MachineApplicable,
- );
- if !items.is_empty() {
- let previous_item = &items[items.len()-1];
- let previous_item_kind_name = match previous_item.node {
- // say "braced struct" because tuple-structs and
- // braceless-empty-struct declarations do take a semicolon
- ItemKind::Struct(..) => Some("braced struct"),
- ItemKind::Enum(..) => Some("enum"),
- ItemKind::Trait(..) => Some("trait"),
- ItemKind::Union(..) => Some("union"),
- _ => None,
- };
- if let Some(name) = previous_item_kind_name {
- err.help(&format!("{} declarations are not followed by a semicolon", name));
- }
- }
- err.emit();
- true
- } else {
- false
- }
- }
-
/// Given a termination token, parses all of the items in a module.
fn parse_mod_items(&mut self, term: &token::Token, inner_lo: Span) -> PResult<'a, Mod> {
let mut items = vec![];
diff --git a/src/test/ui/async-with-closure.rs b/src/test/ui/async-with-closure.rs
new file mode 100644
index 0000000000000..856a778078a61
--- /dev/null
+++ b/src/test/ui/async-with-closure.rs
@@ -0,0 +1,26 @@
+// compile-pass
+// edition:2018
+
+#![feature(async_await, await_macro)]
+
+trait MyClosure {
+ type Args;
+}
+
+impl MyClosure for dyn FnMut() -> R
+where R: 'static {
+ type Args = ();
+}
+
+struct MyStream {
+ x: C::Args,
+}
+
+async fn get_future(_stream: MyStream) {}
+
+async fn f() {
+ let messages: MyStream = unimplemented!();
+ await!(get_future(messages));
+}
+
+fn main() {}
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 599b6c676fb27..e860f2e9df0ad 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -38,7 +38,7 @@ when executed when assertions are disabled.
Use llvm::report_fatal_error for increased robustness.";
/// Parser states for `line_is_url`.
-#[derive(PartialEq)]
+#[derive(Clone, Copy, PartialEq)]
#[allow(non_camel_case_types)]
enum LIUState {
EXP_COMMENT_START,
@@ -56,11 +56,12 @@ enum LIUState {
fn line_is_url(line: &str) -> bool {
use self::LIUState::*;
let mut state: LIUState = EXP_COMMENT_START;
+ let is_url = |w: &str| w.starts_with("http://") || w.starts_with("https://");
for tok in line.split_whitespace() {
match (state, tok) {
- (EXP_COMMENT_START, "//") => state = EXP_LINK_LABEL_OR_URL,
- (EXP_COMMENT_START, "///") => state = EXP_LINK_LABEL_OR_URL,
+ (EXP_COMMENT_START, "//") |
+ (EXP_COMMENT_START, "///") |
(EXP_COMMENT_START, "//!") => state = EXP_LINK_LABEL_OR_URL,
(EXP_LINK_LABEL_OR_URL, w)
@@ -68,14 +69,18 @@ fn line_is_url(line: &str) -> bool {
=> state = EXP_URL,
(EXP_LINK_LABEL_OR_URL, w)
- if w.starts_with("http://") || w.starts_with("https://")
+ if is_url(w)
=> state = EXP_END,
(EXP_URL, w)
- if w.starts_with("http://") || w.starts_with("https://") || w.starts_with("../")
+ if is_url(w) || w.starts_with("../")
=> state = EXP_END,
- (_, _) => return false,
+ (_, w)
+ if w.len() > COLS && is_url(w)
+ => state = EXP_END,
+
+ (_, _) => {}
}
}