about summary refs log tree commit diff
path: root/src/libsyntax
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
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')
-rw-r--r--src/libsyntax/ast.rs81
-rw-r--r--src/libsyntax/parse/parser.rs62
2 files changed, 76 insertions, 67 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 461cb0480d2..1d399f159c8 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -20,7 +20,6 @@ use syntax_pos::{Span, DUMMY_SP};
 use codemap::{respan, Spanned};
 use abi::Abi;
 use ext::hygiene::{Mark, SyntaxContext};
-use parse::parser::{RecoverQPath, PathStyle};
 use print::pprust;
 use ptr::P;
 use rustc_data_structures::indexed_vec;
@@ -485,6 +484,30 @@ impl fmt::Debug for Pat {
 }
 
 impl Pat {
+    pub(super) fn to_ty(&self) -> Option<P<Ty>> {
+        let node = match &self.node {
+            PatKind::Wild => TyKind::Infer,
+            PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) =>
+                TyKind::Path(None, Path::from_ident(ident.span, ident.node)),
+            PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
+            PatKind::Mac(mac) => TyKind::Mac(mac.clone()),
+            PatKind::Ref(pat, mutbl) =>
+                pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?,
+            PatKind::Slice(pats, None, _) if pats.len() == 1 =>
+                pats[0].to_ty().map(TyKind::Slice)?,
+            PatKind::Tuple(pats, None) => {
+                let mut tys = Vec::new();
+                for pat in pats {
+                    tys.push(pat.to_ty()?);
+                }
+                TyKind::Tup(tys)
+            }
+            _ => return None,
+        };
+
+        Some(P(Ty { node, id: self.id, span: self.span }))
+    }
+
     pub fn walk<F>(&self, it: &mut F) -> bool
         where F: FnMut(&Pat) -> bool
     {
@@ -520,38 +543,6 @@ impl Pat {
     }
 }
 
-impl RecoverQPath for Pat {
-    fn to_ty(&self) -> Option<P<Ty>> {
-        let node = match &self.node {
-            PatKind::Wild => TyKind::Infer,
-            PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) =>
-                TyKind::Path(None, Path::from_ident(ident.span, ident.node)),
-            PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
-            PatKind::Mac(mac) => TyKind::Mac(mac.clone()),
-            PatKind::Ref(pat, mutbl) =>
-                pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?,
-            PatKind::Slice(pats, None, _) if pats.len() == 1 =>
-                pats[0].to_ty().map(TyKind::Slice)?,
-            PatKind::Tuple(pats, None) => {
-                let mut tys = Vec::new();
-                for pat in pats {
-                    tys.push(pat.to_ty()?);
-                }
-                TyKind::Tup(tys)
-            }
-            _ => return None,
-        };
-
-        Some(P(Ty { node, id: self.id, span: self.span }))
-    }
-    fn to_recovered(&self, qself: Option<QSelf>, path: Path) -> Self {
-        Self { span: path.span, node: PatKind::Path(qself, path), id: self.id }
-    }
-    fn to_string(&self) -> String {
-        pprust::pat_to_string(self)
-    }
-}
-
 /// A single field in a struct pattern
 ///
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
@@ -919,10 +910,8 @@ impl Expr {
             _ => None,
         }
     }
-}
 
-impl RecoverQPath for Expr {
-    fn to_ty(&self) -> Option<P<Ty>> {
+    pub(super) fn to_ty(&self) -> Option<P<Ty>> {
         let node = match &self.node {
             ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
             ExprKind::Mac(mac) => TyKind::Mac(mac.clone()),
@@ -951,13 +940,6 @@ impl RecoverQPath for Expr {
 
         Some(P(Ty { node, id: self.id, span: self.span }))
     }
-    fn to_recovered(&self, qself: Option<QSelf>, path: 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)
-    }
 }
 
 impl fmt::Debug for Expr {
@@ -1469,19 +1451,6 @@ pub struct Ty {
     pub span: Span,
 }
 
-impl RecoverQPath for Ty {
-    fn to_ty(&self) -> Option<P<Ty>> {
-        Some(P(self.clone()))
-    }
-    fn to_recovered(&self, qself: Option<QSelf>, path: Path) -> Self {
-        Self { span: path.span, node: TyKind::Path(qself, path), id: self.id }
-    }
-    fn to_string(&self) -> String {
-        pprust::ty_to_string(self)
-    }
-    const PATH_STYLE: PathStyle = PathStyle::Type;
-}
-
 impl fmt::Debug for Ty {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "type({})", pprust::ty_to_string(self))
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))
     }