diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-01-16 23:33:45 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-01-17 01:52:47 +0300 |
| commit | 2efe865d22eb85871562b2497ac819efc0174a3d (patch) | |
| tree | 8391f7670462a2536057f9c22c3aa87f90a79d20 /src/libsyntax | |
| parent | 828404684b486a2b741858970a150530228258bb (diff) | |
| download | rust-2efe865d22eb85871562b2497ac819efc0174a3d.tar.gz rust-2efe865d22eb85871562b2497ac819efc0174a3d.zip | |
AST/HIR: Merge ObjectSum and PolyTraitRef
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/diagnostic_list.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 56 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
7 files changed, 83 insertions, 32 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 52f9ec30aec..6c69aa14bcf 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1357,11 +1357,11 @@ pub enum TyKind { /// /// Type parameters are stored in the Path itself Path(Option<QSelf>, Path), - /// Something like `A+B`. Note that `B` must always be a path. - ObjectSum(P<Ty>, TyParamBounds), - /// A type like `for<'a> Foo<&'a Bar>` - PolyTraitRef(TyParamBounds), - /// An `impl TraitA+TraitB` type. + /// A trait object type `Bound1 + Bound2 + Bound3` + /// where `Bound` is a trait or a lifetime. + ObjectSum(TyParamBounds), + /// An `impl Bound1 + Bound2 + Bound3` type + /// where `Bound` is a trait or a lifetime. ImplTrait(TyParamBounds), /// No-op; kept solely so that we can pretty-print faithfully Paren(P<Ty>), diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 9110e989a8a..2b4d1337504 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -15,6 +15,28 @@ // In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable. register_long_diagnostics! { +E0178: r##" +In types, the `+` type operator has low precedence, so it is often necessary +to use parentheses. + +For example: + +```compile_fail,E0178 +trait Foo {} + +struct Bar<'a> { + w: &'a Foo + Copy, // error, use &'a (Foo + Copy) + x: &'a Foo + 'a, // error, use &'a (Foo + 'a) + y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a) + z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a) +} +``` + +More details can be found in [RFC 438]. + +[RFC 438]: https://github.com/rust-lang/rfcs/pull/438 +"##, + E0534: r##" The `inline` attribute was malformed. diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 688df96ffa3..fc3cbf20fb9 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -54,7 +54,6 @@ pub trait AstBuilder { fn ty(&self, span: Span, ty: ast::TyKind) -> P<ast::Ty>; fn ty_path(&self, ast::Path) -> P<ast::Ty>; - fn ty_sum(&self, ast::Path, ast::TyParamBounds) -> P<ast::Ty>; fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>; fn ty_rptr(&self, span: Span, @@ -403,12 +402,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.ty(path.span, ast::TyKind::Path(None, path)) } - fn ty_sum(&self, path: ast::Path, bounds: ast::TyParamBounds) -> P<ast::Ty> { - self.ty(path.span, - ast::TyKind::ObjectSum(self.ty_path(path), - bounds)) - } - // Might need to take bounds as an argument in the future, if you ever want // to generate a bounded existential trait type. fn ty_ident(&self, span: Span, ident: ast::Ident) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1d9abebc7b8..8b045f1b530 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -380,18 +380,14 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { }); TyKind::Path(qself, fld.fold_path(path)) } - TyKind::ObjectSum(ty, bounds) => { - TyKind::ObjectSum(fld.fold_ty(ty), - fld.fold_bounds(bounds)) - } TyKind::Array(ty, e) => { TyKind::Array(fld.fold_ty(ty), fld.fold_expr(e)) } TyKind::Typeof(expr) => { TyKind::Typeof(fld.fold_expr(expr)) } - TyKind::PolyTraitRef(bounds) => { - TyKind::PolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b))) + TyKind::ObjectSum(bounds) => { + TyKind::ObjectSum(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))) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 167fa78d7e0..bae08da0a64 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -40,7 +40,7 @@ use ast::{Visibility, WhereClause}; use ast::{BinOpKind, UnOp}; use {ast, attr}; use codemap::{self, CodeMap, Spanned, spanned, respan}; -use syntax_pos::{self, Span, BytePos, mk_sp}; +use syntax_pos::{self, Span, Pos, BytePos, mk_sp}; use errors::{self, DiagnosticBuilder}; use ext::tt::macro_parser; use parse; @@ -1045,7 +1045,7 @@ impl<'a> Parser<'a> { Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter() .chain(other_bounds.into_vec()) .collect(); - Ok(ast::TyKind::PolyTraitRef(all_bounds)) + Ok(ast::TyKind::ObjectSum(all_bounds)) } } @@ -1267,7 +1267,7 @@ impl<'a> Parser<'a> { return Ok(lhs); } - let bounds = self.parse_ty_param_bounds()?; + let mut bounds = self.parse_ty_param_bounds()?.into_vec(); // In type grammar, `+` is treated like a binary operator, // and hence both L and R side are required. @@ -1277,9 +1277,57 @@ impl<'a> Parser<'a> { "at least one type parameter bound \ must be specified"); } + if let TyKind::Path(None, ref path) = lhs.node { + let poly_trait_ref = PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: TraitRef { path: path.clone(), ref_id: lhs.id }, + span: lhs.span, + }; + let poly_trait_ref = TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None); + bounds.insert(0, poly_trait_ref); + } else { + let mut err = struct_span_err!(self.sess.span_diagnostic, lhs.span, E0178, + "expected a path on the left-hand side \ + of `+`, not `{}`", + pprust::ty_to_string(&lhs)); + err.span_label(lhs.span, &format!("expected a path")); + let hi = bounds.iter().map(|x| match *x { + ast::TraitTyParamBound(ref tr, _) => tr.span.hi, + ast::RegionTyParamBound(ref r) => r.span.hi, + }).max_by_key(|x| x.to_usize()); + let full_span = hi.map(|hi| Span { + lo: lhs.span.lo, + hi: hi, + expn_id: lhs.span.expn_id, + }); + match (&lhs.node, full_span) { + (&TyKind::Rptr(ref lifetime, ref mut_ty), Some(full_span)) => { + let ty_str = pprust::to_string(|s| { + use print::pp::word; + use print::pprust::PrintState; + + word(&mut s.s, "&")?; + s.print_opt_lifetime(lifetime)?; + s.print_mutability(mut_ty.mutbl)?; + s.popen()?; + s.print_type(&mut_ty.ty)?; + s.print_bounds(" +", &bounds)?; + s.pclose() + }); + err.span_suggestion(full_span, "try adding parentheses (per RFC 438):", + ty_str); + } + + _ => { + help!(&mut err, + "perhaps you forgot parentheses? (per RFC 438)"); + } + } + err.emit(); + } let sp = mk_sp(lo, self.prev_span.hi); - let sum = ast::TyKind::ObjectSum(lhs, bounds); + let sum = TyKind::ObjectSum(bounds.into()); Ok(P(Ty {id: ast::DUMMY_NODE_ID, node: sum, span: sp})) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f6ed2350105..31e6f25559d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1028,11 +1028,7 @@ impl<'a> State<'a> { ast::TyKind::Path(Some(ref qself), ref path) => { self.print_qpath(path, qself, false)? } - ast::TyKind::ObjectSum(ref ty, ref bounds) => { - self.print_type(&ty)?; - self.print_bounds("+", &bounds[..])?; - } - ast::TyKind::PolyTraitRef(ref bounds) => { + ast::TyKind::ObjectSum(ref bounds) => { self.print_bounds("", &bounds[..])?; } ast::TyKind::ImplTrait(ref bounds) => { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index cc6ba7adf1a..b0d7a251803 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -342,15 +342,11 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { } visitor.visit_path(path, typ.id); } - TyKind::ObjectSum(ref ty, ref bounds) => { - visitor.visit_ty(ty); - walk_list!(visitor, visit_ty_param_bound, bounds); - } TyKind::Array(ref ty, ref expression) => { visitor.visit_ty(ty); visitor.visit_expr(expression) } - TyKind::PolyTraitRef(ref bounds) => { + TyKind::ObjectSum(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); } TyKind::ImplTrait(ref bounds) => { |
