diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-12-17 01:53:11 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-12-17 19:00:50 +0300 |
| commit | 70e5c3731961b5754bc5b155a75b2f7ff7fb997b (patch) | |
| tree | 0ec785acdd6d1c3ffe94041151b4514424d15e43 /src/libsyntax/ast.rs | |
| parent | af57acef1cd1651861be0bfe77b4f4dd3066ce02 (diff) | |
| download | rust-70e5c3731961b5754bc5b155a75b2f7ff7fb997b.tar.gz rust-70e5c3731961b5754bc5b155a75b2f7ff7fb997b.zip | |
syntax: recovery for incorrect associated item paths like `[T; N]::clone`
Diffstat (limited to 'src/libsyntax/ast.rs')
| -rw-r--r-- | src/libsyntax/ast.rs | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 0d289dbd46b..461cb0480d2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -20,6 +20,7 @@ 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; @@ -519,6 +520,38 @@ 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 }` @@ -877,6 +910,54 @@ impl Expr { true } } + + fn to_bound(&self) -> Option<TyParamBound> { + match &self.node { + ExprKind::Path(None, path) => + Some(TraitTyParamBound(PolyTraitRef::new(Vec::new(), path.clone(), self.span), + TraitBoundModifier::None)), + _ => None, + } + } +} + +impl RecoverQPath for Expr { + 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()), + ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?, + ExprKind::AddrOf(mutbl, expr) => + expr.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?, + ExprKind::Repeat(expr, expr_len) => + expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?, + ExprKind::Array(exprs) if exprs.len() == 1 => + exprs[0].to_ty().map(TyKind::Slice)?, + ExprKind::Tup(exprs) => { + let mut tys = Vec::new(); + for expr in exprs { + tys.push(expr.to_ty()?); + } + TyKind::Tup(tys) + } + ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => + if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) { + TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None) + } else { + return None; + } + _ => 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: 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 { @@ -1388,6 +1469,19 @@ 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)) |
