about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-08 08:39:13 +0000
committerbors <bors@rust-lang.org>2019-03-08 08:39:13 +0000
commitb58a0061a347532c55cd5eb27fd6f47f20889ec6 (patch)
tree09b21029e3a3e07fcab1a73aa9a3bc0e4483c677
parent0547ceb200f0385ba437e1808b468ec81e683c64 (diff)
parent551ea65c87ef567cb22856a769df2a75f2cbb235 (diff)
downloadrust-b58a0061a347532c55cd5eb27fd6f47f20889ec6.tar.gz
rust-b58a0061a347532c55cd5eb27fd6f47f20889ec6.zip
Auto merge of #58903 - estebank:forgetful-delims, r=petrochenkov
Always emit unclosed delimiter diagnostics

Fix #58886.
-rw-r--r--src/librustc_metadata/cstore_impl.rs4
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs2
-rw-r--r--src/libsyntax/parse/mod.rs11
-rw-r--r--src/libsyntax/parse/parser.rs43
-rw-r--r--src/libsyntax/parse/token.rs21
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs7
-rw-r--r--src/test/ui/issues/issue-58856-1.rs6
-rw-r--r--src/test/ui/issues/issue-58856-1.stderr11
-rw-r--r--src/test/ui/issues/issue-58856-2.rs14
-rw-r--r--src/test/ui/issues/issue-58856-2.stderr30
-rw-r--r--src/test/ui/parser/recover-enum2.rs3
-rw-r--r--src/test/ui/parser/recover-enum2.stderr14
-rw-r--r--src/test/ui/parser/unclosed-delimiter-in-dep.rs6
-rw-r--r--src/test/ui/parser/unclosed-delimiter-in-dep.stderr23
-rw-r--r--src/test/ui/parser/unclosed_delim_mod.rs6
-rw-r--r--src/test/ui/parser/unclosed_delim_mod.stderr18
-rw-r--r--src/test/ui/resolve/token-error-correct-3.rs16
-rw-r--r--src/test/ui/resolve/token-error-correct-3.stderr16
18 files changed, 181 insertions, 70 deletions
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index f49b88f14e6..67a249e605e 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -439,8 +439,8 @@ impl cstore::CStore {
 
         let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
         let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
-        let (body, errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
-        emit_unclosed_delims(&errors, &sess.diagnostic());
+        let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
+        emit_unclosed_delims(&mut errors, &sess.diagnostic());
 
         // Mark the attrs as used
         let attrs = data.get_item_attrs(id.index, sess);
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index fe1cffb092b..1a419e7fada 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -761,7 +761,7 @@ pub fn parse(
         else if bb_items.is_empty() && next_items.is_empty() {
             return Failure(
                 parser.span,
-                parser.token,
+                parser.token.clone(),
                 "no rules expected this token in macro call",
             );
         }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b2d4d97d57d..6583458b446 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -6,6 +6,7 @@ use crate::source_map::{SourceMap, FilePathMapping};
 use crate::feature_gate::UnstableFeatures;
 use crate::parse::parser::Parser;
 use crate::symbol::Symbol;
+use crate::syntax::parse::parser::emit_unclosed_delims;
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::diagnostics::plugin::ErrorMap;
 use crate::print::pprust::token_to_string;
@@ -141,8 +142,14 @@ pub fn parse_stream_from_source_str(
     source: String,
     sess: &ParseSess,
     override_span: Option<Span>,
-) -> (TokenStream, Vec<lexer::UnmatchedBrace>) {
-    source_file_to_stream(sess, sess.source_map().new_source_file(name, source), override_span)
+) -> TokenStream {
+    let (stream, mut errors) = source_file_to_stream(
+        sess,
+        sess.source_map().new_source_file(name, source),
+        override_span,
+    );
+    emit_unclosed_delims(&mut errors, &sess.span_diagnostic);
+    stream
 }
 
 /// Creates a new parser from a source string.
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fd5038a8614..7e63da27049 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -46,7 +46,7 @@ use crate::ThinVec;
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
 use crate::symbol::{Symbol, keywords};
 
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{Span, MultiSpan, BytePos, FileName};
 use log::{debug, trace};
@@ -256,8 +256,15 @@ pub struct Parser<'a> {
     /// it gets removed from here. Every entry left at the end gets emitted as an independent
     /// error.
     crate unclosed_delims: Vec<UnmatchedBrace>,
+    last_unexpected_token_span: Option<Span>,
 }
 
+impl<'a> Drop for Parser<'a> {
+    fn drop(&mut self) {
+        let diag = self.diagnostic();
+        emit_unclosed_delims(&mut self.unclosed_delims, diag);
+    }
+}
 
 #[derive(Clone)]
 struct TokenCursor {
@@ -582,6 +589,7 @@ impl<'a> Parser<'a> {
             unmatched_angle_bracket_count: 0,
             max_angle_bracket_count: 0,
             unclosed_delims: Vec::new(),
+            last_unexpected_token_span: None,
         };
 
         let tok = parser.next_tok();
@@ -775,6 +783,8 @@ impl<'a> Parser<'a> {
         } else if inedible.contains(&self.token) {
             // leave it in the input
             Ok(false)
+        } else if self.last_unexpected_token_span == Some(self.span) {
+            FatalError.raise();
         } else {
             let mut expected = edible.iter()
                 .map(|x| TokenType::Token(x.clone()))
@@ -802,6 +812,7 @@ impl<'a> Parser<'a> {
                  (self.sess.source_map().next_point(self.prev_span),
                   format!("expected {} here", expect)))
             };
+            self.last_unexpected_token_span = Some(self.span);
             let mut err = self.fatal(&msg_exp);
             if self.token.is_ident_named("and") {
                 err.span_suggestion_short(
@@ -1497,9 +1508,13 @@ impl<'a> Parser<'a> {
     pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
         maybe_whole!(self, NtTraitItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
+        let mut unclosed_delims = vec![];
         let (mut item, tokens) = self.collect_tokens(|this| {
-            this.parse_trait_item_(at_end, attrs)
+            let item = this.parse_trait_item_(at_end, attrs);
+            unclosed_delims.append(&mut this.unclosed_delims);
+            item
         })?;
+        self.unclosed_delims.append(&mut unclosed_delims);
         // See `parse_item` for why this clause is here.
         if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
             item.tokens = Some(tokens);
@@ -6333,7 +6348,10 @@ impl<'a> Parser<'a> {
                 fn_inputs.append(&mut input);
                 (fn_inputs, recovered)
             } else {
-                return self.unexpected();
+                match self.expect_one_of(&[], &[]) {
+                    Err(err) => return Err(err),
+                    Ok(recovered) => (vec![self_arg], recovered),
+                }
             }
         } else {
             self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
@@ -6459,9 +6477,13 @@ impl<'a> Parser<'a> {
     pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
         maybe_whole!(self, NtImplItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
+        let mut unclosed_delims = vec![];
         let (mut item, tokens) = self.collect_tokens(|this| {
-            this.parse_impl_item_(at_end, attrs)
+            let item = this.parse_impl_item_(at_end, attrs);
+            unclosed_delims.append(&mut this.unclosed_delims);
+            item
         })?;
+        self.unclosed_delims.append(&mut unclosed_delims);
 
         // See `parse_item` for why this clause is here.
         if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
@@ -7781,9 +7803,13 @@ impl<'a> Parser<'a> {
         macros_allowed: bool,
         attributes_allowed: bool,
     ) -> PResult<'a, Option<P<Item>>> {
+        let mut unclosed_delims = vec![];
         let (ret, tokens) = self.collect_tokens(|this| {
-            this.parse_item_implementation(attrs, macros_allowed, attributes_allowed)
+            let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
+            unclosed_delims.append(&mut this.unclosed_delims);
+            item
         })?;
+        self.unclosed_delims.append(&mut unclosed_delims);
 
         // Once we've parsed an item and recorded the tokens we got while
         // parsing we may want to store `tokens` into the item we're about to
@@ -8539,8 +8565,6 @@ impl<'a> Parser<'a> {
             module: self.parse_mod_items(&token::Eof, lo)?,
             span: lo.to(self.span),
         });
-        emit_unclosed_delims(&self.unclosed_delims, self.diagnostic());
-        self.unclosed_delims.clear();
         krate
     }
 
@@ -8571,8 +8595,8 @@ impl<'a> Parser<'a> {
     }
 }
 
-pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors::Handler) {
-    for unmatched in unclosed_delims {
+pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
+    for unmatched in unclosed_delims.iter() {
         let mut err = handler.struct_span_err(unmatched.found_span, &format!(
             "incorrect close delimiter: `{}`",
             pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
@@ -8586,4 +8610,5 @@ pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors
         }
         err.emit();
     }
+    unclosed_delims.clear();
 }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index eec422d6266..2fa4f5263fb 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -10,7 +10,6 @@ use crate::print::pprust;
 use crate::ptr::P;
 use crate::symbol::keywords;
 use crate::syntax::parse::parse_stream_from_source_str;
-use crate::syntax::parse::parser::emit_unclosed_delims;
 use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
 
 use syntax_pos::symbol::{self, Symbol};
@@ -675,9 +674,7 @@ impl Nonterminal {
         // FIXME(#43081): Avoid this pretty-print + reparse hack
         let source = pprust::nonterminal_to_string(self);
         let filename = FileName::macro_expansion_source_code(&source);
-        let (tokens_for_real, errors) =
-            parse_stream_from_source_str(filename, source, sess, Some(span));
-        emit_unclosed_delims(&errors, &sess.span_diagnostic);
+        let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
 
         // During early phases of the compiler the AST could get modified
         // directly (e.g., attributes added or removed) and the internal cache
@@ -740,13 +737,7 @@ fn prepend_attrs(sess: &ParseSess,
         let source = pprust::attr_to_string(attr);
         let macro_filename = FileName::macro_expansion_source_code(&source);
         if attr.is_sugared_doc {
-            let (stream, errors) = parse_stream_from_source_str(
-                macro_filename,
-                source,
-                sess,
-                Some(span),
-            );
-            emit_unclosed_delims(&errors, &sess.span_diagnostic);
+            let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
             builder.push(stream);
             continue
         }
@@ -763,13 +754,7 @@ fn prepend_attrs(sess: &ParseSess,
         // ... and for more complicated paths, fall back to a reparse hack that
         // should eventually be removed.
         } else {
-            let (stream, errors) = parse_stream_from_source_str(
-                macro_filename,
-                source,
-                sess,
-                Some(span),
-            );
-            emit_unclosed_delims(&errors, &sess.span_diagnostic);
+            let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
             brackets.push(stream);
         }
 
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index 4c4b33c0442..a7ac95ba9ef 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -12,7 +12,6 @@ use syntax::ast;
 use syntax::ext::base::ExtCtxt;
 use syntax::parse::lexer::comments;
 use syntax::parse::{self, token, ParseSess};
-use syntax::parse::parser::emit_unclosed_delims;
 use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 use syntax_pos::hygiene::{SyntaxContext, Transparency};
 use syntax_pos::symbol::{keywords, Symbol};
@@ -410,14 +409,12 @@ impl server::TokenStream for Rustc<'_> {
         stream.is_empty()
     }
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        let (tokens, errors) = parse::parse_stream_from_source_str(
+        parse::parse_stream_from_source_str(
             FileName::proc_macro_source_code(src.clone()),
             src.to_string(),
             self.sess,
             Some(self.call_site),
-        );
-        emit_unclosed_delims(&errors, &self.sess.span_diagnostic);
-        tokens
+        )
     }
     fn to_string(&mut self, stream: &Self::TokenStream) -> String {
         stream.to_string()
diff --git a/src/test/ui/issues/issue-58856-1.rs b/src/test/ui/issues/issue-58856-1.rs
new file mode 100644
index 00000000000..db3984cd189
--- /dev/null
+++ b/src/test/ui/issues/issue-58856-1.rs
@@ -0,0 +1,6 @@
+impl A {
+    fn b(self>
+    //~^ ERROR expected one of `)`, `,`, or `:`, found `>`
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-58856-1.stderr b/src/test/ui/issues/issue-58856-1.stderr
new file mode 100644
index 00000000000..20cdf55365f
--- /dev/null
+++ b/src/test/ui/issues/issue-58856-1.stderr
@@ -0,0 +1,11 @@
+error: expected one of `)`, `,`, or `:`, found `>`
+  --> $DIR/issue-58856-1.rs:2:14
+   |
+LL |     fn b(self>
+   |         -    ^
+   |         |    |
+   |         |    help: `)` may belong here
+   |         unclosed delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-58856-2.rs b/src/test/ui/issues/issue-58856-2.rs
new file mode 100644
index 00000000000..acc38e4c201
--- /dev/null
+++ b/src/test/ui/issues/issue-58856-2.rs
@@ -0,0 +1,14 @@
+struct Empty;
+
+trait Howness {}
+
+impl Howness for () {
+    fn how_are_you(&self -> Empty {
+    //~^ ERROR expected one of `)` or `,`, found `->`
+    //~| ERROR method `how_are_you` is not a member of trait `Howness`
+        Empty
+    }
+}
+//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`,
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-58856-2.stderr b/src/test/ui/issues/issue-58856-2.stderr
new file mode 100644
index 00000000000..55a9e9d5cb8
--- /dev/null
+++ b/src/test/ui/issues/issue-58856-2.stderr
@@ -0,0 +1,30 @@
+error: expected one of `)` or `,`, found `->`
+  --> $DIR/issue-58856-2.rs:6:26
+   |
+LL |     fn how_are_you(&self -> Empty {
+   |                   -     -^^
+   |                   |     |
+   |                   |     help: `)` may belong here
+   |                   unclosed delimiter
+
+error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `)`
+  --> $DIR/issue-58856-2.rs:11:1
+   |
+LL |     }
+   |      - expected one of 11 possible tokens here
+LL | }
+   | ^ unexpected token
+
+error[E0407]: method `how_are_you` is not a member of trait `Howness`
+  --> $DIR/issue-58856-2.rs:6:5
+   |
+LL | /     fn how_are_you(&self -> Empty {
+LL | |     //~^ ERROR expected one of `)` or `,`, found `->`
+LL | |     //~| ERROR method `how_are_you` is not a member of trait `Howness`
+LL | |         Empty
+LL | |     }
+   | |_____^ not a member of trait `Howness`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0407`.
diff --git a/src/test/ui/parser/recover-enum2.rs b/src/test/ui/parser/recover-enum2.rs
index 65a18773787..7f2f2cc7ab0 100644
--- a/src/test/ui/parser/recover-enum2.rs
+++ b/src/test/ui/parser/recover-enum2.rs
@@ -25,9 +25,6 @@ fn main() {
         // fail again
         enum Test4 {
             Nope(i32 {}) //~ ERROR: found `{`
-                         //~^ ERROR: found `{`
         }
     }
-    // still recover later
-    let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
 }
diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr
index b308e644ad9..315bfde77c7 100644
--- a/src/test/ui/parser/recover-enum2.stderr
+++ b/src/test/ui/parser/recover-enum2.stderr
@@ -10,17 +10,5 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
 LL |             Nope(i32 {}) //~ ERROR: found `{`
    |                      ^ expected one of 7 possible tokens here
 
-error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `...`, `::`, `<`, `?`, `[`, `_`, `crate`, `dyn`, `extern`, `fn`, `for`, `impl`, `pub`, `unsafe`, `}`, or lifetime, found `{`
-  --> $DIR/recover-enum2.rs:27:22
-   |
-LL |             Nope(i32 {}) //~ ERROR: found `{`
-   |                      ^ expected one of 24 possible tokens here
-
-error: expected expression, found reserved identifier `_`
-  --> $DIR/recover-enum2.rs:32:22
-   |
-LL |     let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
-   |                      ^ expected expression
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.rs b/src/test/ui/parser/unclosed-delimiter-in-dep.rs
new file mode 100644
index 00000000000..6db1b66e9f7
--- /dev/null
+++ b/src/test/ui/parser/unclosed-delimiter-in-dep.rs
@@ -0,0 +1,6 @@
+mod unclosed_delim_mod;
+
+fn main() {
+    let _: usize = unclosed_delim_mod::new();
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
new file mode 100644
index 00000000000..633c63bea91
--- /dev/null
+++ b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
@@ -0,0 +1,23 @@
+error: incorrect close delimiter: `}`
+  --> $DIR/unclosed_delim_mod.rs:5:1
+   |
+LL | pub fn new() -> Result<Value, ()> {
+   |                                   - close delimiter possibly meant for this
+LL |     Ok(Value {
+   |       - un-closed delimiter
+LL |     }
+LL | }
+   | ^ incorrect close delimiter
+
+error[E0308]: mismatched types
+  --> $DIR/unclosed-delimiter-in-dep.rs:4:20
+   |
+LL |     let _: usize = unclosed_delim_mod::new();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^ expected usize, found enum `std::result::Result`
+   |
+   = note: expected type `usize`
+              found type `std::result::Result<unclosed_delim_mod::Value, ()>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/unclosed_delim_mod.rs b/src/test/ui/parser/unclosed_delim_mod.rs
new file mode 100644
index 00000000000..b1664f49dc5
--- /dev/null
+++ b/src/test/ui/parser/unclosed_delim_mod.rs
@@ -0,0 +1,6 @@
+pub struct Value {}
+pub fn new() -> Result<Value, ()> {
+    Ok(Value {
+    }
+}
+//~^ ERROR incorrect close delimiter
diff --git a/src/test/ui/parser/unclosed_delim_mod.stderr b/src/test/ui/parser/unclosed_delim_mod.stderr
new file mode 100644
index 00000000000..cc04eb531cb
--- /dev/null
+++ b/src/test/ui/parser/unclosed_delim_mod.stderr
@@ -0,0 +1,18 @@
+error: incorrect close delimiter: `}`
+  --> $DIR/unclosed_delim_mod.rs:5:1
+   |
+LL | pub fn new() -> Result<Value, ()> {
+   |                                   - close delimiter possibly meant for this
+LL |     Ok(Value {
+   |       - un-closed delimiter
+LL |     }
+LL | }
+   | ^ incorrect close delimiter
+
+error[E0601]: `main` function not found in crate `unclosed_delim_mod`
+   |
+   = note: consider adding a `main` function to `$DIR/unclosed_delim_mod.rs`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/resolve/token-error-correct-3.rs b/src/test/ui/resolve/token-error-correct-3.rs
index b1ca0bbfc57..212b88ac8b0 100644
--- a/src/test/ui/resolve/token-error-correct-3.rs
+++ b/src/test/ui/resolve/token-error-correct-3.rs
@@ -10,16 +10,14 @@ pub mod raw {
     pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P,
                                                                callback: F)
                                                                -> io::Result<bool> {
-        if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
-            callback(path.as_ref(); //~ ERROR expected one of
-            fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
-            //~^ expected (), found enum `std::result::Result`
-            //~| expected type `()`
-            //~| found type `std::result::Result<bool, std::io::Error>`
-            //~| expected one of
+        if !is_directory(path.as_ref()) {
+            //~^ ERROR cannot find function `is_directory`
+            callback(path.as_ref();
+            //~^ ERROR expected one of
+            fs::create_dir_all(path.as_ref()).map(|()| true)
+            //~^ ERROR mismatched types
         } else {
-            //~^ ERROR: expected one of
-            //~| unexpected token
+            //~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
             Ok(false);
         }
 
diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr
index a6bb83c71f3..035a5ede453 100644
--- a/src/test/ui/resolve/token-error-correct-3.stderr
+++ b/src/test/ui/resolve/token-error-correct-3.stderr
@@ -1,31 +1,31 @@
 error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
-  --> $DIR/token-error-correct-3.rs:14:35
+  --> $DIR/token-error-correct-3.rs:15:35
    |
-LL |             callback(path.as_ref(); //~ ERROR expected one of
+LL |             callback(path.as_ref();
    |                     -             ^
    |                     |             |
    |                     |             help: `)` may belong here
    |                     unclosed delimiter
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
-  --> $DIR/token-error-correct-3.rs:20:9
+  --> $DIR/token-error-correct-3.rs:19:9
    |
-LL |             fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
+LL |             fs::create_dir_all(path.as_ref()).map(|()| true)
    |                                                             - expected one of `.`, `;`, `?`, `}`, or an operator here
-...
+LL |             //~^ ERROR mismatched types
 LL |         } else {
    |         ^ unexpected token
 
 error[E0425]: cannot find function `is_directory` in this scope
   --> $DIR/token-error-correct-3.rs:13:13
    |
-LL |         if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
+LL |         if !is_directory(path.as_ref()) {
    |             ^^^^^^^^^^^^ not found in this scope
 
 error[E0308]: mismatched types
-  --> $DIR/token-error-correct-3.rs:15:13
+  --> $DIR/token-error-correct-3.rs:17:13
    |
-LL |             fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
+LL |             fs::create_dir_all(path.as_ref()).map(|()| true)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
    |             |
    |             expected (), found enum `std::result::Result`