提交 f0baec69 编写于 作者: E Eduard Burtescu

syntax: add anonymized type syntax, i.e. impl TraitA+TraitB.

上级 c976e073
......@@ -375,6 +375,9 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyPolyTraitRef(bounds) => {
TyPolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
}
TyImplTrait(bounds) => {
TyImplTrait(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
}
},
span: fld.new_span(span),
}
......
......@@ -427,6 +427,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyPolyTraitRef(ref bounds) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
TyImplTrait(ref bounds) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
TyTypeof(ref expression) => {
visitor.visit_expr(expression)
}
......
......@@ -293,8 +293,10 @@ fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
hir::TyTypeof(self.lower_expr(expr))
}
PolyTraitRef(ref bounds) => {
let bounds = bounds.iter().map(|b| self.lower_ty_param_bound(b)).collect();
hir::TyPolyTraitRef(bounds)
hir::TyPolyTraitRef(self.lower_bounds(bounds))
}
ImplTrait(ref bounds) => {
hir::TyImplTrait(self.lower_bounds(bounds))
}
Mac(_) => panic!("TyMac should have been expanded by now."),
},
......
......@@ -1132,6 +1132,8 @@ pub enum Ty_ {
TyObjectSum(P<Ty>, TyParamBounds),
/// A type like `for<'a> Foo<&'a Bar>`
TyPolyTraitRef(TyParamBounds),
/// An `impl TraitA+TraitB` type.
TyImplTrait(TyParamBounds),
/// Unused for now
TyTypeof(P<Expr>),
/// TyInfer means the type should be inferred instead of it having been
......
......@@ -536,6 +536,9 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
hir::TyPolyTraitRef(ref bounds) => {
self.print_bounds("", &bounds[..])?;
}
hir::TyImplTrait(ref bounds) => {
self.print_bounds("impl ", &bounds[..])?;
}
hir::TyFixedLengthVec(ref ty, ref v) => {
word(&mut self.s, "[")?;
self.print_type(&ty)?;
......
......@@ -1492,6 +1492,9 @@ pub enum Type {
// for<'a> Foo(&'a)
PolyTraitRef(Vec<TyParamBound>),
// impl TraitA+TraitB
ImplTrait(Vec<TyParamBound>),
}
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
......@@ -1777,6 +1780,7 @@ fn clean(&self, cx: &DocContext) -> Type {
}
TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
TyPolyTraitRef(ref bounds) => PolyTraitRef(bounds.clean(cx)),
TyImplTrait(ref bounds) => ImplTrait(bounds.clean(cx)),
TyInfer => Infer,
TyTypeof(..) => panic!("Unimplemented type {:?}", self.node),
}
......
......@@ -539,6 +539,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
Ok(())
}
clean::ImplTrait(ref bounds) => {
write!(f, "impl ")?;
for (i, bound) in bounds.iter().enumerate() {
if i != 0 {
write!(f, " + ")?;
}
write!(f, "{}", *bound)?;
}
Ok(())
}
// It's pretty unsightly to look at `<A as B>::C` in output, and
// we've got hyperlinking on our side, so try to avoid longer
// notation as much as possible by making `C` a hyperlink to trait
......
......@@ -1368,6 +1368,8 @@ pub enum TyKind {
ObjectSum(P<Ty>, TyParamBounds),
/// A type like `for<'a> Foo<&'a Bar>`
PolyTraitRef(TyParamBounds),
/// An `impl TraitA+TraitB` type.
ImplTrait(TyParamBounds),
/// No-op; kept solely so that we can pretty-print faithfully
Paren(P<Ty>),
/// Unused for now
......
......@@ -277,7 +277,10 @@ pub fn new() -> Features {
(active, cfg_target_has_atomic, "1.9.0", Some(32976)),
// Allows `..` in tuple (struct) patterns
(active, dotdot_in_tuple_patterns, "1.10.0", Some(33627))
(active, dotdot_in_tuple_patterns, "1.10.0", Some(33627)),
// Allows `impl Trait` in function return types.
(active, conservative_impl_trait, "1.12.0", Some(34511))
);
declare_features! (
......@@ -952,6 +955,10 @@ fn visit_ty(&mut self, ty: &ast::Ty) {
ast::TyKind::BareFn(ref bare_fn_ty) => {
self.check_abi(bare_fn_ty.abi, ty.span);
}
ast::TyKind::ImplTrait(..) => {
gate_feature_post!(&self, conservative_impl_trait, ty.span,
"`impl Trait` is experimental");
}
_ => {}
}
visit::walk_ty(self, ty)
......
......@@ -397,6 +397,9 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyKind::PolyTraitRef(bounds) => {
TyKind::PolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
}
TyKind::ImplTrait(bounds) => {
TyKind::ImplTrait(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
}
TyKind::Mac(mac) => {
TyKind::Mac(fld.fold_mac(mac))
}
......
......@@ -1051,7 +1051,7 @@ pub fn get_lifetime(&mut self) -> ast::Ident {
pub fn parse_for_in_type(&mut self) -> PResult<'a, TyKind> {
/*
Parses whatever can come after a `for` keyword in a type.
The `for` has already been consumed.
The `for` hasn't been consumed.
Deprecated:
......@@ -1091,6 +1091,23 @@ pub fn parse_for_in_type(&mut self) -> PResult<'a, TyKind> {
}
}
pub fn parse_impl_trait_type(&mut self) -> PResult<'a, TyKind> {
/*
Parses whatever can come after a `impl` keyword in a type.
The `impl` has already been consumed.
*/
let bounds = self.parse_ty_param_bounds(BoundParsingMode::Modified)?;
if !bounds.iter().any(|b| if let TraitTyParamBound(..) = *b { true } else { false }) {
let last_span = self.last_span;
self.span_err(last_span, "at least one trait must be specified");
}
Ok(ast::TyKind::ImplTrait(bounds))
}
pub fn parse_ty_path(&mut self) -> PResult<'a, TyKind> {
Ok(TyKind::Path(None, self.parse_path(PathStyle::Type)?))
}
......@@ -1406,6 +1423,8 @@ pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
self.parse_borrowed_pointee()?
} else if self.check_keyword(keywords::For) {
self.parse_for_in_type()?
} else if self.eat_keyword(keywords::Impl) {
self.parse_impl_trait_type()?
} else if self.token_is_bare_fn_keyword() {
// BARE FUNCTION
self.parse_ty_bare_fn(Vec::new())?
......
......@@ -1018,6 +1018,9 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
ast::TyKind::PolyTraitRef(ref bounds) => {
try!(self.print_bounds("", &bounds[..]));
}
ast::TyKind::ImplTrait(ref bounds) => {
try!(self.print_bounds("impl ", &bounds[..]));
}
ast::TyKind::FixedLengthVec(ref ty, ref v) => {
try!(word(&mut self.s, "["));
try!(self.print_type(&ty));
......
......@@ -343,6 +343,9 @@ pub fn walk_ty<V: Visitor>(visitor: &mut V, typ: &Ty) {
TyKind::PolyTraitRef(ref bounds) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
TyKind::ImplTrait(ref bounds) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
TyKind::Typeof(ref expression) => {
visitor.visit_expr(expression)
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册