about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-21 13:34:09 +0000
committerbors <bors@rust-lang.org>2017-12-21 13:34:09 +0000
commiteff3de0927c36e6483ccb8a35c3d2da6e063de0b (patch)
treecee7a79c7aa3c865552efc2838844519e14d5101 /src/libsyntax/parse
parentde38f49528b537414385d42a66dda711c8c8a309 (diff)
parentbdd3f5b240bac62e6e49c12313ebf9ebbc1dfea4 (diff)
downloadrust-eff3de0927c36e6483ccb8a35c3d2da6e063de0b.tar.gz
rust-eff3de0927c36e6483ccb8a35c3d2da6e063de0b.zip
Auto merge of #46904 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 5 pull requests

- Successful merges: #46827, #46853, #46860, #46861, #46887
- Failed merges:
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs62
1 files changed, 51 insertions, 11 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2aac7ef39f2..d9434539246 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -169,11 +169,49 @@ enum PrevTokenKind {
     Other,
 }
 
-pub(crate) trait RecoverQPath: Sized {
+trait RecoverQPath: Sized {
+    const PATH_STYLE: PathStyle = PathStyle::Expr;
     fn to_ty(&self) -> Option<P<Ty>>;
     fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self;
     fn to_string(&self) -> String;
-    const PATH_STYLE: PathStyle = PathStyle::Expr;
+}
+
+impl RecoverQPath for Ty {
+    const PATH_STYLE: PathStyle = PathStyle::Type;
+    fn to_ty(&self) -> Option<P<Ty>> {
+        Some(P(self.clone()))
+    }
+    fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
+        Self { span: path.span, node: TyKind::Path(qself, path), id: self.id }
+    }
+    fn to_string(&self) -> String {
+        pprust::ty_to_string(self)
+    }
+}
+
+impl RecoverQPath for Pat {
+    fn to_ty(&self) -> Option<P<Ty>> {
+        self.to_ty()
+    }
+    fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
+        Self { span: path.span, node: PatKind::Path(qself, path), id: self.id }
+    }
+    fn to_string(&self) -> String {
+        pprust::pat_to_string(self)
+    }
+}
+
+impl RecoverQPath for Expr {
+    fn to_ty(&self) -> Option<P<Ty>> {
+        self.to_ty()
+    }
+    fn to_recovered(&self, qself: Option<QSelf>, path: ast::Path) -> Self {
+        Self { span: path.span, node: ExprKind::Path(qself, path),
+               id: self.id, attrs: self.attrs.clone() }
+    }
+    fn to_string(&self) -> String {
+        pprust::expr_to_string(self)
+    }
 }
 
 /* ident is handled by common.rs */
@@ -1432,7 +1470,7 @@ impl<'a> Parser<'a> {
 
     // Parse a type
     pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
-        self.parse_ty_common(true)
+        self.parse_ty_common(true, true)
     }
 
     /// Parse a type in restricted contexts where `+` is not permitted.
@@ -1441,10 +1479,11 @@ impl<'a> Parser<'a> {
     /// Example 2: `value1 as TYPE + value2`
     ///     `+` is prohibited to avoid interactions with expression grammar.
     fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
-        self.parse_ty_common(false)
+        self.parse_ty_common(false, true)
     }
 
-    fn parse_ty_common(&mut self, allow_plus: bool) -> PResult<'a, P<Ty>> {
+    fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
+                       -> PResult<'a, P<Ty>> {
         maybe_whole!(self, NtTy, |x| x);
 
         let lo = self.span;
@@ -1577,7 +1616,7 @@ impl<'a> Parser<'a> {
 
         // Try to recover from use of `+` with incorrect priority.
         self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
-        let ty = self.maybe_recover_from_bad_qpath(ty)?;
+        let ty = self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)?;
 
         Ok(P(ty))
     }
@@ -1633,9 +1672,10 @@ impl<'a> Parser<'a> {
     }
 
     // Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
-    fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T) -> PResult<'a, T> {
+    fn maybe_recover_from_bad_qpath<T: RecoverQPath>(&mut self, base: T, allow_recovery: bool)
+                                                     -> PResult<'a, T> {
         // Do not add `::` to expected tokens.
-        if self.token != token::ModSep {
+        if !allow_recovery || self.token != token::ModSep {
             return Ok(base);
         }
         let ty = match base.to_ty() {
@@ -1969,7 +2009,7 @@ impl<'a> Parser<'a> {
                     |p| p.parse_ty())?;
                 self.bump(); // `)`
                 let output = if self.eat(&token::RArrow) {
-                    Some(self.parse_ty_no_plus()?)
+                    Some(self.parse_ty_common(false, false)?)
                 } else {
                     None
                 };
@@ -2376,7 +2416,7 @@ impl<'a> Parser<'a> {
         }
 
         let expr = Expr { node: ex, span: lo.to(hi), id: ast::DUMMY_NODE_ID, attrs };
-        let expr = self.maybe_recover_from_bad_qpath(expr)?;
+        let expr = self.maybe_recover_from_bad_qpath(expr, true)?;
 
         return Ok(P(expr));
     }
@@ -3743,7 +3783,7 @@ impl<'a> Parser<'a> {
         }
 
         let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
-        let pat = self.maybe_recover_from_bad_qpath(pat)?;
+        let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
 
         Ok(P(pat))
     }