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 | |
| parent | 828404684b486a2b741858970a150530228258bb (diff) | |
| download | rust-2efe865d22eb85871562b2497ac819efc0174a3d.tar.gz rust-2efe865d22eb85871562b2497ac819efc0174a3d.zip | |
AST/HIR: Merge ObjectSum and PolyTraitRef
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 6 | ||||
| -rw-r--r-- | src/librustc/hir/lowering.rs | 7 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 11 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 6 | ||||
| -rw-r--r-- | src/librustc_incremental/calculate_svh/svh_visitor.rs | 2 | ||||
| -rw-r--r-- | src/librustc_passes/ast_validation.rs | 3 | ||||
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 88 | ||||
| -rw-r--r-- | src/librustc_typeck/diagnostics.rs | 50 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 29 | ||||
| -rw-r--r-- | src/librustdoc/html/format.rs | 13 | ||||
| -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 | ||||
| -rw-r--r-- | src/test/compile-fail/E0172.rs | 16 | ||||
| -rw-r--r-- | src/test/compile-fail/E0178.rs | 3 | ||||
| -rw-r--r-- | src/test/compile-fail/trait-bounds-not-on-struct.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs | 2 | ||||
| -rw-r--r-- | src/test/pretty/path-type-bounds.rs | 6 |
22 files changed, 119 insertions, 240 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index c244c33728c..001a5f6e586 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -562,15 +562,11 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyPath(ref qpath) => { visitor.visit_qpath(qpath, typ.id, typ.span); } - TyObjectSum(ref ty, ref bounds) => { - visitor.visit_ty(ty); - walk_list!(visitor, visit_ty_param_bound, bounds); - } TyArray(ref ty, length) => { visitor.visit_ty(ty); visitor.visit_nested_body(length) } - TyPolyTraitRef(ref bounds) => { + TyObjectSum(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); } TyImplTrait(ref bounds) => { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index bdd54c547e3..9a0ef6537ce 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -308,9 +308,6 @@ impl<'a> LoweringContext<'a> { span: t.span, }))) } - TyKind::ObjectSum(ref ty, ref bounds) => { - hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds)) - } TyKind::Array(ref ty, ref length) => { let length = self.lower_expr(length); hir::TyArray(self.lower_ty(ty), @@ -320,8 +317,8 @@ impl<'a> LoweringContext<'a> { let expr = self.lower_expr(expr); hir::TyTypeof(self.record_body(expr, None)) } - TyKind::PolyTraitRef(ref bounds) => { - hir::TyPolyTraitRef(self.lower_bounds(bounds)) + TyKind::ObjectSum(ref bounds) => { + hir::TyObjectSum(self.lower_bounds(bounds)) } TyKind::ImplTrait(ref bounds) => { hir::TyImplTrait(self.lower_bounds(bounds)) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 075358c576c..c3ae0e3f276 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1214,12 +1214,11 @@ pub enum Ty_ { /// /// Type parameters may be stored in each `PathSegment`. TyPath(QPath), - - /// Something like `A+B`. Note that `B` must always be a path. - TyObjectSum(P<Ty>, TyParamBounds), - /// A type like `for<'a> Foo<&'a Bar>` - TyPolyTraitRef(TyParamBounds), - /// An `impl TraitA+TraitB` type. + /// A trait object type `Bound1 + Bound2 + Bound3` + /// where `Bound` is a trait or a lifetime. + TyObjectSum(TyParamBounds), + /// An `impl Bound1 + Bound2 + Bound3` type + /// where `Bound` is a trait or a lifetime. TyImplTrait(TyParamBounds), /// Unused for now TyTypeof(BodyId), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index b84a3308315..c314145721f 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -418,11 +418,7 @@ impl<'a> State<'a> { hir::TyPath(ref qpath) => { self.print_qpath(qpath, false)? } - hir::TyObjectSum(ref ty, ref bounds) => { - self.print_type(&ty)?; - self.print_bounds("+", &bounds[..])?; - } - hir::TyPolyTraitRef(ref bounds) => { + hir::TyObjectSum(ref bounds) => { self.print_bounds("", &bounds[..])?; } hir::TyImplTrait(ref bounds) => { diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 4bb12667bbc..c2abba5cce3 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -441,7 +441,6 @@ enum SawTyComponent { SawTyTup, SawTyPath, SawTyObjectSum, - SawTyPolyTraitRef, SawTyImplTrait, SawTyTypeof, SawTyInfer @@ -458,7 +457,6 @@ fn saw_ty(node: &Ty_) -> SawTyComponent { TyTup(..) => SawTyTup, TyPath(_) => SawTyPath, TyObjectSum(..) => SawTyObjectSum, - TyPolyTraitRef(..) => SawTyPolyTraitRef, TyImplTrait(..) => SawTyImplTrait, TyTypeof(..) => SawTyTypeof, TyInfer => SawTyInfer diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 52bdd014933..e38fcbb5f6b 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -143,8 +143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { err.emit(); }); } - TyKind::ObjectSum(_, ref bounds) | - TyKind::PolyTraitRef(ref bounds) => { + TyKind::ObjectSum(ref bounds) => { self.no_questions_in_bounds(bounds, "trait object types", false); } _ => {} diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index bc984949fc6..bcb82c85f24 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -73,7 +73,7 @@ use std::iter; use syntax::{abi, ast}; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::symbol::{Symbol, keywords}; -use syntax_pos::{Span, Pos}; +use syntax_pos::Span; use errors::DiagnosticBuilder; pub trait AstConv<'gcx, 'tcx> { @@ -930,87 +930,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { decl_ty.subst(self.tcx(), substs) } - fn ast_ty_to_object_trait_ref(&self, - rscope: &RegionScope, - span: Span, - ty: &hir::Ty, - bounds: &[hir::TyParamBound]) - -> Ty<'tcx> - { - /*! - * In a type like `Foo + Send`, we want to wait to collect the - * full set of bounds before we make the object type, because we - * need them to infer a region bound. (For example, if we tried - * made a type from just `Foo`, then it wouldn't be enough to - * infer a 'static bound, and hence the user would get an error.) - * So this function is used when we're dealing with a sum type to - * convert the LHS. It only accepts a type that refers to a trait - * name, and reports an error otherwise. - */ - - let tcx = self.tcx(); - match ty.node { - hir::TyPath(hir::QPath::Resolved(None, ref path)) => { - if let Def::Trait(trait_def_id) = path.def { - self.trait_path_to_object_type(rscope, - path.span, - trait_def_id, - ty.id, - path.segments.last().unwrap(), - span, - partition_bounds(bounds)) - } else { - struct_span_err!(tcx.sess, ty.span, E0172, - "expected a reference to a trait") - .span_label(ty.span, &format!("expected a trait")) - .emit(); - tcx.types.err - } - } - _ => { - let mut err = struct_span_err!(tcx.sess, ty.span, E0178, - "expected a path on the left-hand side \ - of `+`, not `{}`", - tcx.map.node_to_pretty_string(ty.id)); - err.span_label(ty.span, &format!("expected a path")); - let hi = bounds.iter().map(|x| match *x { - hir::TraitTyParamBound(ref tr, _) => tr.span.hi, - hir::RegionTyParamBound(ref r) => r.span.hi, - }).max_by_key(|x| x.to_usize()); - let full_span = hi.map(|hi| Span { - lo: ty.span.lo, - hi: hi, - expn_id: ty.span.expn_id, - }); - match (&ty.node, full_span) { - (&hir::TyRptr(ref lifetime, ref mut_ty), Some(full_span)) => { - let ty_str = hir::print::to_string(&tcx.map, |s| { - use syntax::print::pp::word; - use syntax::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(); - tcx.types.err - } - } - } - /// Transform a PolyTraitRef into a PolyExistentialTraitRef by /// removing the dummy Self type (TRAIT_OBJECT_DUMMY_SELF). fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>) @@ -1534,9 +1453,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::TySlice(ref ty) => { tcx.mk_slice(self.ast_ty_to_ty(rscope, &ty)) } - hir::TyObjectSum(ref ty, ref bounds) => { - self.ast_ty_to_object_trait_ref(rscope, ast_ty.span, ty, bounds) - } hir::TyPtr(ref mt) => { tcx.mk_ptr(ty::TypeAndMut { ty: self.ast_ty_to_ty(rscope, &mt.ty), @@ -1609,7 +1525,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } tcx.mk_fn_ptr(bare_fn_ty) } - hir::TyPolyTraitRef(ref bounds) => { + hir::TyObjectSum(ref bounds) => { self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds) } hir::TyImplTrait(ref bounds) => { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 1a971be64d8..3617b1f0a7d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1864,55 +1864,6 @@ fn bar(foo: Foo) -> u32 { ``` "##, -E0172: r##" -This error means that an attempt was made to specify the type of a variable with -a combination of a concrete type and a trait. Consider the following example: - -```compile_fail,E0172 -fn foo(bar: i32+std::fmt::Display) {} -``` - -The code is trying to specify that we want to receive a signed 32-bit integer -which also implements `Display`. This doesn't make sense: when we pass `i32`, a -concrete type, it implicitly includes all of the traits that it implements. -This includes `Display`, `Debug`, `Clone`, and a host of others. - -If `i32` implements the trait we desire, there's no need to specify the trait -separately. If it does not, then we need to `impl` the trait for `i32` before -passing it into `foo`. Either way, a fixed definition for `foo` will look like -the following: - -``` -fn foo(bar: i32) {} -``` - -To learn more about traits, take a look at the Book: - -https://doc.rust-lang.org/book/traits.html -"##, - -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 -"##, - E0182: r##" You bound an associated type in an expression path which is not allowed. @@ -4152,6 +4103,7 @@ register_diagnostics! { // E0163, // merged into E0071 // E0167, // E0168, +// E0172, // non-trait found in a type sum, moved to resolve // E0173, // manual implementations of unboxed closure traits are experimental // E0174, E0183, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 71165cd3f40..77ca6ef34b8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1504,9 +1504,6 @@ pub enum Type { // _ Infer, - // for<'a> Foo(&'a) - PolyTraitRef(Vec<TyParamBound>), - // impl TraitA+TraitB ImplTrait(Vec<TyParamBound>), } @@ -1768,24 +1765,26 @@ impl Clean<Type> for hir::Ty { trait_: box resolve_type(cx, trait_path.clean(cx), self.id) } } - TyObjectSum(ref lhs, ref bounds) => { - let lhs_ty = lhs.clean(cx); + TyObjectSum(ref bounds) => { + let lhs_ty = bounds[0].clean(cx); match lhs_ty { - ResolvedPath { path, typarams: None, did, is_generic } => { - ResolvedPath { - path: path, - typarams: Some(bounds.clean(cx)), - did: did, - is_generic: is_generic, + TraitBound(poly_trait, ..) => { + match poly_trait.trait_ { + ResolvedPath { path, typarams: None, did, is_generic } => { + ResolvedPath { + path: path, + typarams: Some(bounds[1..].clean(cx)), + did: did, + is_generic: is_generic, + } + } + _ => Infer // shouldn't happen } } - _ => { - lhs_ty // shouldn't happen - } + _ => Infer // shouldn't happen } } 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), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 716ad05401d..d25c4184f3c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -679,19 +679,6 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: } } } - clean::PolyTraitRef(ref bounds) => { - for (i, bound) in bounds.iter().enumerate() { - if i != 0 { - write!(f, " + ")?; - } - if f.alternate() { - write!(f, "{:#}", *bound)?; - } else { - write!(f, "{}", *bound)?; - } - } - Ok(()) - } clean::ImplTrait(ref bounds) => { write!(f, "impl ")?; for (i, bound) in bounds.iter().enumerate() { 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) => { diff --git a/src/test/compile-fail/E0172.rs b/src/test/compile-fail/E0172.rs deleted file mode 100644 index 485a31d9666..00000000000 --- a/src/test/compile-fail/E0172.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn foo(bar: i32+std::fmt::Display) {} - //~^ ERROR E0172 - //~| NOTE expected a trait - -fn main() { -} diff --git a/src/test/compile-fail/E0178.rs b/src/test/compile-fail/E0178.rs index 6527465e0b7..ffc5940c95c 100644 --- a/src/test/compile-fail/E0178.rs +++ b/src/test/compile-fail/E0178.rs @@ -17,12 +17,15 @@ struct Bar<'a> { x: &'a Foo + 'a, //~^ ERROR E0178 //~| NOTE expected a path + //~| ERROR at least one non-builtin trait is required for an object type y: &'a mut Foo + 'a, //~^ ERROR E0178 //~| NOTE expected a path + //~| ERROR at least one non-builtin trait is required for an object type z: fn() -> Foo + 'a, //~^ ERROR E0178 //~| NOTE expected a path + //~| ERROR at least one non-builtin trait is required for an object type } fn main() { diff --git a/src/test/compile-fail/trait-bounds-not-on-struct.rs b/src/test/compile-fail/trait-bounds-not-on-struct.rs index 081efa429c3..cabe0fd48ed 100644 --- a/src/test/compile-fail/trait-bounds-not-on-struct.rs +++ b/src/test/compile-fail/trait-bounds-not-on-struct.rs @@ -11,6 +11,6 @@ struct Foo; -fn foo(_x: Box<Foo + Send>) { } //~ ERROR expected a reference to a trait +fn foo(_x: Box<Foo + Send>) { } //~ ERROR expected trait, found struct `Foo` fn main() { } diff --git a/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs b/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs index fc2ed83b272..c009644c561 100644 --- a/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs +++ b/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs @@ -13,8 +13,10 @@ fn main() { //~^ ERROR expected a path //~| HELP try adding parentheses //~| SUGGESTION let _: &(Copy + 'static); + //~| ERROR at least one non-builtin trait is required for an object type let _: &'static Copy + 'static; //~^ ERROR expected a path //~| HELP try adding parentheses //~| SUGGESTION let _: &'static (Copy + 'static); + //~| ERROR at least one non-builtin trait is required for an object type } diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs index 06d57b261e6..651d2b67941 100644 --- a/src/test/pretty/path-type-bounds.rs +++ b/src/test/pretty/path-type-bounds.rs @@ -16,10 +16,10 @@ trait Tr { } impl Tr for isize { } -fn foo<'a>(x: Box<Tr+ Sync + 'a>) -> Box<Tr+ Sync + 'a> { x } +fn foo<'a>(x: Box< Tr + Sync + 'a>) -> Box< Tr + Sync + 'a> { x } fn main() { - let x: Box<Tr+ Sync>; + let x: Box< Tr + Sync>; - Box::new(1isize) as Box<Tr+ Sync>; + Box::new(1isize) as Box< Tr + Sync>; } |
