about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/parse/diagnostics.rs99
-rw-r--r--src/libsyntax/parse/parser.rs39
-rw-r--r--src/libsyntax_ext/format.rs5
-rw-r--r--src/test/ui/codemap_tests/bad-format-args.stderr4
-rw-r--r--src/test/ui/issues/issue-22644.stderr11
-rw-r--r--src/test/ui/issues/issue-34255-1.stderr11
-rw-r--r--src/test/ui/issues/issue-39616.stderr2
-rw-r--r--src/test/ui/issues/issue-44406.stderr5
-rw-r--r--src/test/ui/lifetime_starts_expressions.stderr11
-rw-r--r--src/test/ui/macros/missing-comma.stderr2
-rw-r--r--src/test/ui/parser/issue-33262.stderr2
-rw-r--r--src/test/ui/parser/macro/trait-object-macro-matcher.stderr2
-rw-r--r--src/test/ui/parser/recover-enum2.stderr2
-rw-r--r--src/test/ui/parser/recover-from-bad-variant.stderr11
-rw-r--r--src/test/ui/parser/removed-syntax-mut-vec-ty.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-record.stderr2
-rw-r--r--src/test/ui/parser/trait-object-lifetime-parens.stderr2
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-method.stderr7
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-variant.stderr7
-rw-r--r--src/test/ui/type/ascription/issue-34255-1.rs15
-rw-r--r--src/test/ui/type/ascription/issue-34255-1.stderr30
-rw-r--r--src/test/ui/type/ascription/issue-47666.rs5
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr13
-rw-r--r--src/test/ui/type/ascription/issue-54516.rs6
-rw-r--r--src/test/ui/type/ascription/issue-54516.stderr13
-rw-r--r--src/test/ui/type/ascription/issue-60933.rs4
-rw-r--r--src/test/ui/type/ascription/issue-60933.stderr13
-rw-r--r--src/test/ui/type/type-ascription-instead-of-initializer.stderr2
-rw-r--r--src/test/ui/type/type-ascription-instead-of-statement-end.stderr16
29 files changed, 225 insertions, 118 deletions
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 0e88a0ee289..f4fc87506f3 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -2,6 +2,7 @@ use crate::ast::{
     self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
     Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData,
 };
+use crate::feature_gate::{feature_err, UnstableFeatures};
 use crate::parse::{SeqSep, PResult, Parser, ParseSess};
 use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType};
 use crate::parse::token::{self, TokenKind};
@@ -326,8 +327,8 @@ impl<'a> Parser<'a> {
             self.token.is_keyword(kw::Return) ||
             self.token.is_keyword(kw::While)
         );
-        let cm = self.sess.source_map();
-        match (cm.lookup_line(self.token.span.lo()), cm.lookup_line(sp.lo())) {
+        let sm = self.sess.source_map();
+        match (sm.lookup_line(self.token.span.lo()), sm.lookup_line(sp.lo())) {
             (Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
                 // The spans are in different lines, expected `;` and found `let` or `return`.
                 // High likelihood that it is only a missing `;`.
@@ -365,9 +366,53 @@ impl<'a> Parser<'a> {
                 err.span_label(self.token.span, "unexpected token");
             }
         }
+        self.maybe_annotate_with_ascription(&mut err, false);
         Err(err)
     }
 
+    pub fn maybe_annotate_with_ascription(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        maybe_expected_semicolon: bool,
+    ) {
+        if let Some((sp, likely_path)) = self.last_type_ascription {
+            let sm = self.sess.source_map();
+            let next_pos = sm.lookup_char_pos(self.token.span.lo());
+            let op_pos = sm.lookup_char_pos(sp.hi());
+
+            if likely_path {
+                err.span_suggestion(
+                    sp,
+                    "maybe write a path separator here",
+                    "::".to_string(),
+                    match self.sess.unstable_features {
+                        UnstableFeatures::Disallow => Applicability::MachineApplicable,
+                        _ => Applicability::MaybeIncorrect,
+                    },
+                );
+            } else if op_pos.line != next_pos.line && maybe_expected_semicolon {
+                err.span_suggestion(
+                    sp,
+                    "try using a semicolon",
+                    ";".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            } else if let UnstableFeatures::Disallow = self.sess.unstable_features {
+                err.span_label(sp, "tried to parse a type due to this");
+            } else {
+                err.span_label(sp, "tried to parse a type due to this type ascription");
+            }
+            if let UnstableFeatures::Disallow = self.sess.unstable_features {
+                // Give extra information about type ascription only if it's a nightly compiler.
+            } else {
+                err.note("`#![feature(type_ascription)]` lets you annotate an expression with a \
+                          type: `<expr>: <type>`");
+                err.note("for more information, see \
+                          https://github.com/rust-lang/rust/issues/23416");
+            }
+        }
+    }
+
     /// 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]) {
@@ -556,7 +601,7 @@ impl<'a> Parser<'a> {
         .collect::<Vec<_>>();
 
         if !discriminant_spans.is_empty() && has_fields {
-            let mut err = crate::feature_gate::feature_err(
+            let mut err = feature_err(
                 sess,
                 sym::arbitrary_enum_discriminant,
                 discriminant_spans.clone(),
@@ -769,8 +814,8 @@ impl<'a> Parser<'a> {
                 return Ok(recovered);
             }
         }
-        let cm = self.sess.source_map();
-        match (cm.lookup_line(prev_sp.lo()), cm.lookup_line(sp.lo())) {
+        let sm = self.sess.source_map();
+        match (sm.lookup_line(prev_sp.lo()), sm.lookup_line(sp.lo())) {
             (Ok(ref a), Ok(ref b)) if a.line == b.line => {
                 // When the spans are in the same line, it means that the only content
                 // between them is whitespace, point only at the found token.
@@ -887,47 +932,9 @@ impl<'a> Parser<'a> {
             self.look_ahead(2, |t| t.is_ident()) ||
             self.look_ahead(1, |t| t == &token::Colon) &&  // `foo:bar:baz`
             self.look_ahead(2, |t| t.is_ident()) ||
-            self.look_ahead(1, |t| t == &token::ModSep) &&  // `foo:bar::baz`
-            self.look_ahead(2, |t| t.is_ident())
-    }
-
-    crate fn bad_type_ascription(
-        &self,
-        err: &mut DiagnosticBuilder<'a>,
-        lhs_span: Span,
-        cur_op_span: Span,
-        next_sp: Span,
-        maybe_path: bool,
-    ) {
-        err.span_label(self.token.span, "expecting a type here because of type ascription");
-        let cm = self.sess.source_map();
-        let next_pos = cm.lookup_char_pos(next_sp.lo());
-        let op_pos = cm.lookup_char_pos(cur_op_span.hi());
-        if op_pos.line != next_pos.line {
-            err.span_suggestion(
-                cur_op_span,
-                "try using a semicolon",
-                ";".to_string(),
-                Applicability::MaybeIncorrect,
-            );
-        } else {
-            if maybe_path {
-                err.span_suggestion(
-                    cur_op_span,
-                    "maybe you meant to write a path separator here",
-                    "::".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            } else {
-                err.note("`#![feature(type_ascription)]` lets you annotate an \
-                          expression with a type: `<expr>: <type>`")
-                    .span_note(
-                        lhs_span,
-                        "this expression expects an ascribed type after the colon",
-                    )
-                    .help("this might be indicative of a syntax error elsewhere");
-            }
-        }
+            self.look_ahead(1, |t| t == &token::ModSep) &&
+            (self.look_ahead(2, |t| t.is_ident()) ||   // `foo:bar::baz`
+             self.look_ahead(2, |t| t == &token::Lt))  // `foo:bar::<baz>`
     }
 
     crate fn recover_seq_parse_error(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1d4d02c7325..da388694637 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -239,6 +239,7 @@ pub struct Parser<'a> {
     /// error.
     crate unclosed_delims: Vec<UnmatchedBrace>,
     crate last_unexpected_token_span: Option<Span>,
+    crate last_type_ascription: Option<(Span, bool /* likely path typo */)>,
     /// If present, this `Parser` is not parsing Rust code but rather a macro call.
     crate subparser_name: Option<&'static str>,
 }
@@ -502,6 +503,7 @@ impl<'a> Parser<'a> {
             max_angle_bracket_count: 0,
             unclosed_delims: Vec::new(),
             last_unexpected_token_span: None,
+            last_type_ascription: None,
             subparser_name,
         };
 
@@ -1422,7 +1424,10 @@ impl<'a> Parser<'a> {
             }
         } else {
             let msg = format!("expected type, found {}", self.this_token_descr());
-            return Err(self.fatal(&msg));
+            let mut err = self.fatal(&msg);
+            err.span_label(self.token.span, "expected type");
+            self.maybe_annotate_with_ascription(&mut err, true);
+            return Err(err);
         };
 
         let span = lo.to(self.prev_span);
@@ -2823,10 +2828,11 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an associative expression with operators of at least `min_prec` precedence.
-    fn parse_assoc_expr_with(&mut self,
-                                 min_prec: usize,
-                                 lhs: LhsExpr)
-                                 -> PResult<'a, P<Expr>> {
+    fn parse_assoc_expr_with(
+        &mut self,
+        min_prec: usize,
+        lhs: LhsExpr,
+    ) -> PResult<'a, P<Expr>> {
         let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
             expr
         } else {
@@ -2840,9 +2846,11 @@ impl<'a> Parser<'a> {
                 self.parse_prefix_expr(attrs)?
             }
         };
+        let last_type_ascription_set = self.last_type_ascription.is_some();
 
         match (self.expr_is_complete(&lhs), AssocOp::from_token(&self.token)) {
             (true, None) => {
+                self.last_type_ascription = None;
                 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
                 return Ok(lhs);
             }
@@ -2857,12 +2865,14 @@ impl<'a> Parser<'a> {
             // If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
             // `if x { a } else { b } && if y { c } else { d }`
             if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
+                self.last_type_ascription = None;
                 // These cases are ambiguous and can't be identified in the parser alone
                 let sp = self.sess.source_map().start_point(self.token.span);
                 self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
                 return Ok(lhs);
             }
             (true, Some(ref op)) if !op.can_continue_expr_unambiguously() => {
+                self.last_type_ascription = None;
                 return Ok(lhs);
             }
             (true, Some(_)) => {
@@ -2921,21 +2931,9 @@ impl<'a> Parser<'a> {
                 continue
             } else if op == AssocOp::Colon {
                 let maybe_path = self.could_ascription_be_path(&lhs.node);
-                let next_sp = self.token.span;
+                self.last_type_ascription = Some((self.prev_span, maybe_path));
 
-                lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) {
-                    Ok(lhs) => lhs,
-                    Err(mut err) => {
-                        self.bad_type_ascription(
-                            &mut err,
-                            lhs_span,
-                            cur_op_span,
-                            next_sp,
-                            maybe_path,
-                        );
-                        return Err(err);
-                    }
-                };
+                lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
                 continue
             } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
                 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
@@ -3020,6 +3018,9 @@ impl<'a> Parser<'a> {
 
             if let Fixity::None = fixity { break }
         }
+        if last_type_ascription_set {
+            self.last_type_ascription = None;
+        }
         Ok(lhs)
     }
 
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 2d296147a1f..e53660b6568 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -141,7 +141,10 @@ fn parse_args<'a>(
 
     while p.token != token::Eof {
         if !p.eat(&token::Comma) {
-            return Err(ecx.struct_span_err(p.token.span, "expected token: `,`"));
+            let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`");
+            err.span_label(p.token.span, "expected `,`");
+            p.maybe_annotate_with_ascription(&mut err, false);
+            return Err(err);
         }
         if p.token == token::Eof {
             break;
diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr
index c424eb08a7a..5b01314d8ad 100644
--- a/src/test/ui/codemap_tests/bad-format-args.stderr
+++ b/src/test/ui/codemap_tests/bad-format-args.stderr
@@ -10,13 +10,13 @@ error: expected token: `,`
   --> $DIR/bad-format-args.rs:3:16
    |
 LL |     format!("" 1);
-   |                ^
+   |                ^ expected `,`
 
 error: expected token: `,`
   --> $DIR/bad-format-args.rs:4:19
    |
 LL |     format!("", 1 1);
-   |                   ^
+   |                   ^ expected `,`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr
index 4f0dc0a4887..0fe167963c3 100644
--- a/src/test/ui/issues/issue-22644.stderr
+++ b/src/test/ui/issues/issue-22644.stderr
@@ -87,15 +87,12 @@ error: expected type, found `4`
   --> $DIR/issue-22644.rs:34:28
    |
 LL |     println!("{}", a: &mut 4);
-   |                            ^ expecting a type here because of type ascription
+   |                     -      ^ expected type
+   |                     |
+   |                     tried to parse a type due to this type ascription
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-note: this expression expects an ascribed type after the colon
-  --> $DIR/issue-22644.rs:34:20
-   |
-LL |     println!("{}", a: &mut 4);
-   |                    ^
-   = help: this might be indicative of a syntax error elsewhere
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr
index 0218a7abeaa..acb093b5142 100644
--- a/src/test/ui/issues/issue-34255-1.stderr
+++ b/src/test/ui/issues/issue-34255-1.stderr
@@ -2,15 +2,12 @@ error: expected type, found `42`
   --> $DIR/issue-34255-1.rs:8:24
    |
 LL |     Test::Drill(field: 42);
-   |                        ^^ expecting a type here because of type ascription
+   |                      - ^^ expected type
+   |                      |
+   |                      tried to parse a type due to this type ascription
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-note: this expression expects an ascribed type after the colon
-  --> $DIR/issue-34255-1.rs:8:17
-   |
-LL |     Test::Drill(field: 42);
-   |                 ^^^^^
-   = help: this might be indicative of a syntax error elsewhere
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-39616.stderr b/src/test/ui/issues/issue-39616.stderr
index e24ffcdb0d9..75eb55fa50b 100644
--- a/src/test/ui/issues/issue-39616.stderr
+++ b/src/test/ui/issues/issue-39616.stderr
@@ -2,7 +2,7 @@ error: expected type, found `0`
   --> $DIR/issue-39616.rs:1:12
    |
 LL | fn foo(a: [0; 1]) {}
-   |            ^
+   |            ^ expected type
 
 error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
   --> $DIR/issue-39616.rs:1:16
diff --git a/src/test/ui/issues/issue-44406.stderr b/src/test/ui/issues/issue-44406.stderr
index 14b3b8cc5c8..108542c9b6f 100644
--- a/src/test/ui/issues/issue-44406.stderr
+++ b/src/test/ui/issues/issue-44406.stderr
@@ -15,7 +15,10 @@ LL |         bar(baz: $rest)
    |                - help: try using a semicolon: `;`
 ...
 LL |     foo!(true);
-   |          ^^^^ expecting a type here because of type ascription
+   |          ^^^^ expected type
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr
index 84e4c87ebc4..bacba10b55f 100644
--- a/src/test/ui/lifetime_starts_expressions.stderr
+++ b/src/test/ui/lifetime_starts_expressions.stderr
@@ -12,15 +12,12 @@ error: expected type, found keyword `loop`
   --> $DIR/lifetime_starts_expressions.rs:6:26
    |
 LL |     loop { break 'label: loop { break 'label 42; }; }
-   |                          ^^^^ expecting a type here because of type ascription
+   |                        - ^^^^ expected type
+   |                        |
+   |                        tried to parse a type due to this type ascription
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-note: this expression expects an ascribed type after the colon
-  --> $DIR/lifetime_starts_expressions.rs:6:12
-   |
-LL |     loop { break 'label: loop { break 'label 42; }; }
-   |            ^^^^^^^^^^^^
-   = help: this might be indicative of a syntax error elsewhere
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr
index d5b6d86b20f..f96848f8239 100644
--- a/src/test/ui/macros/missing-comma.stderr
+++ b/src/test/ui/macros/missing-comma.stderr
@@ -2,7 +2,7 @@ error: expected token: `,`
   --> $DIR/missing-comma.rs:19:19
    |
 LL |     println!("{}" a);
-   |                   ^
+   |                   ^ expected `,`
 
 error: no rules expected the token `b`
   --> $DIR/missing-comma.rs:21:12
diff --git a/src/test/ui/parser/issue-33262.stderr b/src/test/ui/parser/issue-33262.stderr
index c2491df903b..2aff3283935 100644
--- a/src/test/ui/parser/issue-33262.stderr
+++ b/src/test/ui/parser/issue-33262.stderr
@@ -2,7 +2,7 @@ error: expected type, found `{`
   --> $DIR/issue-33262.rs:4:22
    |
 LL |     for i in 0..a as { }
-   |                      ^
+   |                      ^ expected type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
index 19c5c82f82c..f02f60e4bfb 100644
--- a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
+++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
@@ -2,7 +2,7 @@ error: expected type, found `'static`
   --> $DIR/trait-object-macro-matcher.rs:9:8
    |
 LL |     m!('static);
-   |        ^^^^^^^
+   |        ^^^^^^^ expected type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr
index 9ed2e6f5eb6..2311887a6fb 100644
--- a/src/test/ui/parser/recover-enum2.stderr
+++ b/src/test/ui/parser/recover-enum2.stderr
@@ -2,7 +2,7 @@ error: expected type, found `{`
   --> $DIR/recover-enum2.rs:6:18
    |
 LL |             abc: {},
-   |                  ^
+   |                  ^ expected type
 
 error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
   --> $DIR/recover-enum2.rs:25:22
diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr
index d525bd3f4c6..b46d3ca9c23 100644
--- a/src/test/ui/parser/recover-from-bad-variant.stderr
+++ b/src/test/ui/parser/recover-from-bad-variant.stderr
@@ -2,15 +2,12 @@ error: expected type, found `3`
   --> $DIR/recover-from-bad-variant.rs:7:26
    |
 LL |     let x = Enum::Foo(a: 3, b: 4);
-   |                          ^ expecting a type here because of type ascription
+   |                        - ^ expected type
+   |                        |
+   |                        tried to parse a type due to this type ascription
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-note: this expression expects an ascribed type after the colon
-  --> $DIR/recover-from-bad-variant.rs:7:23
-   |
-LL |     let x = Enum::Foo(a: 3, b: 4);
-   |                       ^
-   = help: this might be indicative of a syntax error elsewhere
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo`
   --> $DIR/recover-from-bad-variant.rs:10:9
diff --git a/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr
index a759716b5a9..02b518e2516 100644
--- a/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr
+++ b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr
@@ -2,7 +2,7 @@ error: expected type, found keyword `mut`
   --> $DIR/removed-syntax-mut-vec-ty.rs:1:11
    |
 LL | type v = [mut isize];
-   |           ^^^
+   |           ^^^ expected type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-record.stderr b/src/test/ui/parser/removed-syntax-record.stderr
index 730d5e2712b..0a1655840b5 100644
--- a/src/test/ui/parser/removed-syntax-record.stderr
+++ b/src/test/ui/parser/removed-syntax-record.stderr
@@ -2,7 +2,7 @@ error: expected type, found `{`
   --> $DIR/removed-syntax-record.rs:1:10
    |
 LL | type t = { f: () };
-   |          ^
+   |          ^ expected type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr
index a31b7aea8fe..7ffc26e9ede 100644
--- a/src/test/ui/parser/trait-object-lifetime-parens.stderr
+++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr
@@ -29,7 +29,7 @@ error: expected type, found `'a`
   --> $DIR/trait-object-lifetime-parens.rs:9:17
    |
 LL |     let _: Box<('a) + Trait>;
-   |         -       ^^
+   |         -       ^^ expected type
    |         |
    |         while parsing the type for `_`
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
index 15ec087b1cc..4a8d2f57d89 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
@@ -2,9 +2,12 @@ error: expected type, found `"foo"`
   --> $DIR/type-ascription-instead-of-method.rs:2:13
    |
 LL |     Box:new("foo".to_string())
-   |        -    ^^^^^ expecting a type here because of type ascription
+   |        -    ^^^^^ expected type
    |        |
-   |        help: maybe you meant to write a path separator here: `::`
+   |        help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
index 5719a667a84..7e9a31c06c8 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
@@ -2,9 +2,12 @@ error: expected type, found `""`
   --> $DIR/type-ascription-instead-of-variant.rs:2:25
    |
 LL |     let _ = Option:Some("");
-   |                   -     ^^ expecting a type here because of type ascription
+   |                   -     ^^ expected type
    |                   |
-   |                   help: maybe you meant to write a path separator here: `::`
+   |                   help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs
new file mode 100644
index 00000000000..c11a248d3c7
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-34255-1.rs
@@ -0,0 +1,15 @@
+struct Reactor {
+    input_cells: Vec<usize>,
+}
+
+impl Reactor {
+    pub fn new() -> Self {
+        input_cells: Vec::new()
+        //~^ ERROR cannot find value `input_cells` in this scope
+        //~| ERROR parenthesized type parameters may only be used with a `Fn` trait
+        //~| ERROR wrong number of type arguments: expected 1, found 0
+        //~| WARNING this was previously accepted by the compiler but is being phased out
+    }
+}
+
+// This case isn't currently being handled gracefully, including for completeness.
diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr
new file mode 100644
index 00000000000..531455b82b4
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-34255-1.stderr
@@ -0,0 +1,30 @@
+error[E0425]: cannot find value `input_cells` in this scope
+  --> $DIR/issue-34255-1.rs:7:9
+   |
+LL |         input_cells: Vec::new()
+   |         ^^^^^^^^^^^ a field by this name exists in `Self`
+
+error: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-34255-1.rs:7:30
+   |
+LL |         input_cells: Vec::new()
+   |                              ^^
+   |
+   = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+
+error[E0601]: `main` function not found in crate `issue_34255_1`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-34255-1.rs`
+
+error[E0107]: wrong number of type arguments: expected 1, found 0
+  --> $DIR/issue-34255-1.rs:7:22
+   |
+LL |         input_cells: Vec::new()
+   |                      ^^^^^^^^^^ expected 1 type argument
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0107, E0425, E0601.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs
new file mode 100644
index 00000000000..ceb1dd89dae
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-47666.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found
+}
+
+// This case isn't currently being handled gracefully due to the macro invocation.
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
new file mode 100644
index 00000000000..7aa899f795c
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -0,0 +1,13 @@
+error: expected type, found reserved keyword `box`
+  --> $DIR/issue-47666.rs:2:25
+   |
+LL |     let _ = Option:Some(vec![0, 1]);
+   |                         ^^^^^^^^^^
+   |                         |
+   |                         expected type
+   |                         in this macro invocation
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs
new file mode 100644
index 00000000000..6d65760e299
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-54516.rs
@@ -0,0 +1,6 @@
+use std::collections::BTreeMap;
+
+fn main() {
+    println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
+    //~^ ERROR expected token: `,`
+}
diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr
new file mode 100644
index 00000000000..a846f3bc320
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-54516.stderr
@@ -0,0 +1,13 @@
+error: expected token: `,`
+  --> $DIR/issue-54516.rs:4:58
+   |
+LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
+   |                            -                             ^ expected `,`
+   |                            |
+   |                            help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs
new file mode 100644
index 00000000000..8fb06c887bd
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-60933.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let u: usize = std::mem:size_of::<u32>();
+    //~^ ERROR expected one of
+}
diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr
new file mode 100644
index 00000000000..c2fc7bbcfc8
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-60933.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `::`, or `;`, found `(`
+  --> $DIR/issue-60933.rs:2:43
+   |
+LL |     let u: usize = std::mem:size_of::<u32>();
+   |                            -              ^ expected one of `!`, `::`, or `;` here
+   |                            |
+   |                            help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
index a22d25697d8..3fe676de59d 100644
--- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
@@ -2,7 +2,7 @@ error: expected type, found `10`
   --> $DIR/type-ascription-instead-of-initializer.rs:2:31
    |
 LL |     let x: Vec::with_capacity(10, 20);
-   |         --                    ^^
+   |         --                    ^^ expected type
    |         ||
    |         |help: use `=` if you meant to assign
    |         while parsing the type for `x`
diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr
index 1f8989db814..8fbcb3969a7 100644
--- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr
@@ -4,21 +4,21 @@ error: expected type, found `0`
 LL |     println!("test"):
    |                     - help: try using a semicolon: `;`
 LL |     0;
-   |     ^ expecting a type here because of type ascription
+   |     ^ expected type
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: expected type, found `0`
   --> $DIR/type-ascription-instead-of-statement-end.rs:9:23
    |
 LL |     println!("test"): 0;
-   |                       ^ expecting a type here because of type ascription
+   |                     - ^ expected type
+   |                     |
+   |                     tried to parse a type due to this type ascription
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-note: this expression expects an ascribed type after the colon
-  --> $DIR/type-ascription-instead-of-statement-end.rs:9:5
-   |
-LL |     println!("test"): 0;
-   |     ^^^^^^^^^^^^^^^^
-   = help: this might be indicative of a syntax error elsewhere
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
 
 error: aborting due to 2 previous errors