syntax: recovery for incorrect associated item paths like [T; N]::clone
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user