about summary refs log tree commit diff
path: root/src/librustc_parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-02-01 23:31:51 +0000
committerbors <bors@rust-lang.org>2020-02-01 23:31:51 +0000
commite5b150edafc0e72cd7f5f3f67a4e8b417d515b01 (patch)
treef29b6c6172ad7b834afac0155d93036c028cfc63 /src/librustc_parse
parent13db6501c7273cd1997ce20e15106f362e5613c4 (diff)
parent87bb0c4389b09bfa86780eb014a4a2de95a3840b (diff)
downloadrust-e5b150edafc0e72cd7f5f3f67a4e8b417d515b01.tar.gz
rust-e5b150edafc0e72cd7f5f3f67a4e8b417d515b01.zip
Auto merge of #68752 - JohnTitor:rollup-zz3u4xl, r=JohnTitor
Rollup of 7 pull requests

Successful merges:

 - #68460 (Use BufWriter for emitting MIR)
 - #68681 (Suggest path separator for single-colon typos)
 - #68688 ([docs] remind bug reporters to update nightly)
 - #68704 (Ignore `build` dir formatting)
 - #68727 (Remove a comment about pretty printer in formatting tests)
 - #68736 (Remove `Alloc` in favor of `AllocRef`)
 - #68740 (Do not suggest things named underscore)

Failed merges:

r? @ghost
Diffstat (limited to 'src/librustc_parse')
-rw-r--r--src/librustc_parse/parser/path.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs
index 0358458c099..a09eb42dcfe 100644
--- a/src/librustc_parse/parser/path.rs
+++ b/src/librustc_parse/parser/path.rs
@@ -71,7 +71,9 @@ impl<'a> Parser<'a> {
             debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count);
         }
 
-        self.expect(&token::ModSep)?;
+        if !self.recover_colon_before_qpath_proj() {
+            self.expect(&token::ModSep)?;
+        }
 
         let qself = QSelf { ty, path_span, position: path.segments.len() };
         self.parse_path_segments(&mut path.segments, style)?;
@@ -79,6 +81,39 @@ impl<'a> Parser<'a> {
         Ok((qself, Path { segments: path.segments, span: lo.to(self.prev_span) }))
     }
 
+    /// Recover from an invalid single colon, when the user likely meant a qualified path.
+    /// We avoid emitting this if not followed by an identifier, as our assumption that the user
+    /// intended this to be a qualified path may not be correct.
+    ///
+    /// ```ignore (diagnostics)
+    /// <Bar as Baz<T>>:Qux
+    ///                ^ help: use double colon
+    /// ```
+    fn recover_colon_before_qpath_proj(&mut self) -> bool {
+        if self.token.kind != token::Colon
+            || self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident())
+        {
+            return false;
+        }
+
+        self.bump(); // colon
+
+        self.diagnostic()
+            .struct_span_err(
+                self.prev_span,
+                "found single colon before projection in qualified path",
+            )
+            .span_suggestion(
+                self.prev_span,
+                "use double colon",
+                "::".to_string(),
+                Applicability::MachineApplicable,
+            )
+            .emit();
+
+        true
+    }
+
     /// Parses simple paths.
     ///
     /// `path = [::] segment+`