about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-13 07:48:01 +0000
committerbors <bors@rust-lang.org>2019-04-13 07:48:01 +0000
commitaa35e73b258789d93b080e361542d7aa99e7fcd6 (patch)
tree35016b7e8e0758d8c516c47be108c62eb3ede473 /src/libsyntax
parent99da733f7f38ce8fe68453e859b7ac96bf7caa0f (diff)
parentba173135becd5681baa67551cafa20ce9a3017e2 (diff)
downloadrust-aa35e73b258789d93b080e361542d7aa99e7fcd6.tar.gz
rust-aa35e73b258789d93b080e361542d7aa99e7fcd6.zip
Auto merge of #59922 - Centril:rollup-0qmx4jg, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #59781 (Remove check_match from const_eval)
 - #59820 (proc_macro: stop using LEB128 for RPC.)
 - #59846 (clarify what the item is in "not a module" error)
 - #59847 (Error when using `catch` after `try`)
 - #59859 (Suggest removing `?` to resolve type errors.)
 - #59862 (Tweak unstable diagnostic output)
 - #59866 (Recover from missing semicolon based on the found token)
 - #59892 (Impl RawFd conversion traits for WASI TcpListener, TcpStream and UdpSocket)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/feature_gate.rs67
-rw-r--r--src/libsyntax/json.rs24
-rw-r--r--src/libsyntax/parse/parser.rs36
3 files changed, 90 insertions, 37 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index dcb55fb572f..f77593ed02a 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -903,7 +903,7 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
     ("thread_local", Whitelisted, template!(Word), Gated(Stability::Unstable,
                                         "thread_local",
                                         "`#[thread_local]` is an experimental feature, and does \
-                                         not currently handle destructors.",
+                                         not currently handle destructors",
                                         cfg_fn!(thread_local))),
 
     ("rustc_on_unimplemented", Whitelisted, template!(List:
@@ -1438,18 +1438,34 @@ pub enum GateStrength {
     Soft,
 }
 
-pub fn emit_feature_err(sess: &ParseSess, feature: &str, span: Span, issue: GateIssue,
-                        explain: &str) {
+pub fn emit_feature_err(
+    sess: &ParseSess,
+    feature: &str,
+    span: Span,
+    issue: GateIssue,
+    explain: &str,
+) {
     feature_err(sess, feature, span, issue, explain).emit();
 }
 
-pub fn feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue: GateIssue,
-                       explain: &str) -> DiagnosticBuilder<'a> {
+pub fn feature_err<'a>(
+    sess: &'a ParseSess,
+    feature: &str,
+    span: Span,
+    issue: GateIssue,
+    explain: &str,
+) -> DiagnosticBuilder<'a> {
     leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
 }
 
-fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue: GateIssue,
-                           explain: &str, level: GateStrength) -> DiagnosticBuilder<'a> {
+fn leveled_feature_err<'a>(
+    sess: &'a ParseSess,
+    feature: &str,
+    span: Span,
+    issue: GateIssue,
+    explain: &str,
+    level: GateStrength,
+) -> DiagnosticBuilder<'a> {
     let diag = &sess.span_diagnostic;
 
     let issue = match issue {
@@ -1457,23 +1473,26 @@ fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue
         GateIssue::Library(lib) => lib,
     };
 
-    let explanation = match issue {
-        None | Some(0) => explain.to_owned(),
-        Some(n) => format!("{} (see issue #{})", explain, n)
-    };
-
     let mut err = match level {
         GateStrength::Hard => {
-            diag.struct_span_err_with_code(span, &explanation, stringify_error_code!(E0658))
+            diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658))
         }
-        GateStrength::Soft => diag.struct_span_warn(span, &explanation),
+        GateStrength::Soft => diag.struct_span_warn(span, explain),
     };
 
+    match issue {
+        None | Some(0) => {}  // We still accept `0` as a stand-in for backwards compatibility
+        Some(n) => {
+            err.note(&format!(
+                "for more information, see https://github.com/rust-lang/rust/issues/{}",
+                n,
+            ));
+        }
+    }
+
     // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
     if sess.unstable_features.is_nightly_build() {
-        err.help(&format!("add #![feature({})] to the \
-                           crate attributes to enable",
-                          feature));
+        err.help(&format!("add #![feature({})] to the crate attributes to enable", feature));
     }
 
     // If we're on stable and only emitting a "soft" warning, add a note to
@@ -1488,10 +1507,10 @@ fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue
 }
 
 const EXPLAIN_BOX_SYNTAX: &str =
-    "box expression syntax is experimental; you can call `Box::new` instead.";
+    "box expression syntax is experimental; you can call `Box::new` instead";
 
 pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
-    "attributes on expressions are experimental.";
+    "attributes on expressions are experimental";
 
 pub const EXPLAIN_ASM: &str =
     "inline assembly is not stable enough for use and is subject to change";
@@ -1685,10 +1704,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
     fn visit_name(&mut self, sp: Span, name: ast::Name) {
         if !name.as_str().is_ascii() {
-            gate_feature_post!(&self,
-                               non_ascii_idents,
-                               self.context.parse_sess.source_map().def_span(sp),
-                               "non-ascii idents are not fully supported.");
+            gate_feature_post!(
+                &self,
+                non_ascii_idents,
+                self.context.parse_sess.source_map().def_span(sp),
+                "non-ascii idents are not fully supported"
+            );
         }
     }
 
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 9acd0d099a0..838dfc62646 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -348,19 +348,17 @@ impl DiagnosticSpanLine {
     /// `span` within the line.
     fn from_span(span: Span, je: &JsonEmitter) -> Vec<DiagnosticSpanLine> {
         je.sm.span_to_lines(span)
-             .map(|lines| {
-                 let fm = &*lines.file;
-                 lines.lines
-                      .iter()
-                      .map(|line| {
-                          DiagnosticSpanLine::line_from_source_file(fm,
-                                                                line.line_index,
-                                                                line.start_col.0 + 1,
-                                                                line.end_col.0 + 1)
-                      })
-                     .collect()
-             })
-            .unwrap_or_else(|_| vec![])
+            .map(|lines| {
+                let fm = &*lines.file;
+                lines.lines
+                    .iter()
+                    .map(|line| DiagnosticSpanLine::line_from_source_file(
+                        fm,
+                        line.line_index,
+                        line.start_col.0 + 1,
+                        line.end_col.0 + 1,
+                    )).collect()
+            }).unwrap_or_else(|_| vec![])
     }
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b51b7fd1ef5..a5adb37f745 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -851,8 +851,34 @@ impl<'a> Parser<'a> {
                 }
             }
 
+            let is_semi_suggestable = expected.iter().any(|t| match t {
+                TokenType::Token(token::Semi) => true, // we expect a `;` here
+                _ => false,
+            }) && ( // a `;` would be expected before the current keyword
+                self.token.is_keyword(keywords::Break) ||
+                self.token.is_keyword(keywords::Continue) ||
+                self.token.is_keyword(keywords::For) ||
+                self.token.is_keyword(keywords::If) ||
+                self.token.is_keyword(keywords::Let) ||
+                self.token.is_keyword(keywords::Loop) ||
+                self.token.is_keyword(keywords::Match) ||
+                self.token.is_keyword(keywords::Return) ||
+                self.token.is_keyword(keywords::While)
+            );
             let cm = self.sess.source_map();
             match (cm.lookup_line(self.span.lo()), cm.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 `;`.
+                    err.span_suggestion_short(
+                        label_sp,
+                        "a semicolon may be missing here",
+                        ";".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                    err.emit();
+                    return Ok(true);
+                }
                 (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 at the found token in that case:
@@ -4091,7 +4117,15 @@ impl<'a> Parser<'a> {
     {
         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
         attrs.extend(iattrs);
-        Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs))
+        if self.eat_keyword(keywords::Catch) {
+            let mut error = self.struct_span_err(self.prev_span,
+                                                 "keyword `catch` cannot follow a `try` block");
+            error.help("try using `match` on the result of the `try` block instead");
+            error.emit();
+            Err(error)
+        } else {
+            Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs))
+        }
     }
 
     // `match` token already eaten