Permalink
Browse files

Auto merge of #39110 - petrochenkov:sum, r=eddyb

Merge ObjectSum and PolyTraitRef in AST/HIR + some other refactoring

`ObjectSum` and `PolyTraitRef` are the same thing (list of bounds), they exist separately only due to parser quirks. The second commit merges them.

The first commit replaces `Path` with `Ty` in (not yet supported) equality predicates. They are parsed as types anyway and arbitrary types can always be disguised as paths using aliases, so this doesn't add any new functionality.

The third commit uses `Vec` instead of `P<[T]>` in AST. AST is not immutable like HIR and `Vec`s are more convenient for it, unnecessary conversions are also avoided.

The last commit renames `parse_ty_sum` (which is used for parsing types in general) into `parse_ty`, and renames `parse_ty` (which is used restricted contexts where `+` is not permitted due to operator priorities or other reasons) into `parse_ty_no_plus`.

This is the first part of #39085 (comment) and #39080 focused on data changes and mechanical renaming, I'll submit a PR with parser changes a bit later.

r? @eddyb
  • Loading branch information...
2 parents 0825c96 + 66ef5f2 commit a167c042abed695a049abf3919ce929765e6cc30 @bors bors committed Jan 17, 2017
@@ -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) => {
+ TyTraitObject(ref bounds) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
TyImplTrait(ref bounds) => {
@@ -740,12 +736,12 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
walk_list!(visitor, visit_lifetime, bounds);
}
&WherePredicate::EqPredicate(WhereEqPredicate{id,
- ref path,
- ref ty,
+ ref lhs_ty,
+ ref rhs_ty,
..}) => {
visitor.visit_id(id);
- visitor.visit_path(path, id);
- visitor.visit_ty(ty);
+ visitor.visit_ty(lhs_ty);
+ visitor.visit_ty(rhs_ty);
}
}
}
@@ -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::TraitObject(ref bounds) => {
+ hir::TyTraitObject(self.lower_bounds(bounds))
}
TyKind::ImplTrait(ref bounds) => {
hir::TyImplTrait(self.lower_bounds(bounds))
@@ -599,7 +596,7 @@ impl<'a> LoweringContext<'a> {
}
}
- fn lower_ty_params(&mut self, tps: &P<[TyParam]>, add_bounds: &NodeMap<Vec<TyParamBound>>)
+ fn lower_ty_params(&mut self, tps: &Vec<TyParam>, add_bounds: &NodeMap<Vec<TyParamBound>>)
-> hir::HirVec<hir::TyParam> {
tps.iter().map(|tp| {
self.lower_ty_param(tp, add_bounds.get(&tp.id).map_or(&[][..], |x| &x))
@@ -719,13 +716,13 @@ impl<'a> LoweringContext<'a> {
})
}
WherePredicate::EqPredicate(WhereEqPredicate{ id,
- ref path,
- ref ty,
+ ref lhs_ty,
+ ref rhs_ty,
span}) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
id: id,
- path: self.lower_path(id, path, ParamMode::Explicit, false),
- ty: self.lower_ty(ty),
+ lhs_ty: self.lower_ty(lhs_ty),
+ rhs_ty: self.lower_ty(rhs_ty),
span: span,
})
}
@@ -403,8 +403,8 @@ pub struct WhereRegionPredicate {
pub struct WhereEqPredicate {
pub id: NodeId,
pub span: Span,
- pub path: Path,
- pub ty: P<Ty>,
+ pub lhs_ty: P<Ty>,
+ pub rhs_ty: P<Ty>,
}
pub type CrateConfig = HirVec<P<MetaItem>>;
@@ -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.
+ TyTraitObject(TyParamBounds),
+ /// An `impl Bound1 + Bound2 + Bound3` type
+ /// where `Bound` is a trait or a lifetime.
TyImplTrait(TyParamBounds),
/// Unused for now
TyTypeof(BodyId),
@@ -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::TyTraitObject(ref bounds) => {
self.print_bounds("", &bounds[..])?;
}
hir::TyImplTrait(ref bounds) => {
@@ -2023,11 +2019,13 @@ impl<'a> State<'a> {
}
}
}
- &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref path, ref ty, ..}) => {
- self.print_path(path, false)?;
+ &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty,
+ ref rhs_ty,
+ ..}) => {
+ self.print_type(lhs_ty)?;
space(&mut self.s)?;
self.word_space("=")?;
- self.print_type(&ty)?;
+ self.print_type(rhs_ty)?;
}
}
}
@@ -323,12 +323,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
self.visit_lifetime(bound);
}
}
- &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ id,
- ref path,
- ref ty,
- .. }) => {
- self.visit_path(path, id);
- self.visit_ty(&ty);
+ &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty,
+ ref rhs_ty,
+ .. }) => {
+ self.visit_ty(lhs_ty);
+ self.visit_ty(rhs_ty);
}
}
}
@@ -441,7 +441,6 @@ enum SawTyComponent {
SawTyTup,
SawTyPath,
SawTyObjectSum,
- SawTyPolyTraitRef,
SawTyImplTrait,
SawTyTypeof,
SawTyInfer
@@ -457,8 +456,7 @@ fn saw_ty(node: &Ty_) -> SawTyComponent {
TyNever => SawTyNever,
TyTup(..) => SawTyTup,
TyPath(_) => SawTyPath,
- TyObjectSum(..) => SawTyObjectSum,
- TyPolyTraitRef(..) => SawTyPolyTraitRef,
+ TyTraitObject(..) => SawTyObjectSum,
TyImplTrait(..) => SawTyImplTrait,
TyTypeof(..) => SawTyTypeof,
TyInfer => SawTyInfer
@@ -143,8 +143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
err.emit();
});
}
- TyKind::ObjectSum(_, ref bounds) |
- TyKind::PolyTraitRef(ref bounds) => {
+ TyKind::TraitObject(ref bounds) => {
self.no_questions_in_bounds(bounds, "trait object types", false);
}
_ => {}
@@ -853,7 +853,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
}
&hir::WherePredicate::RegionPredicate(_) => {}
&hir::WherePredicate::EqPredicate(ref eq_pred) => {
- self.visit_ty(&eq_pred.ty);
+ self.visit_ty(&eq_pred.rhs_ty);
}
}
}
@@ -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>)
@@ -1428,7 +1347,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
match path.def {
Def::Trait(trait_def_id) => {
// N.B. this case overlaps somewhat with
- // TyObjectSum, see that fn for details
+ // TyTraitObject, see that fn for details
assert_eq!(opt_self_ty, None);
tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
@@ -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::TyTraitObject(ref bounds) => {
self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds)
}
hir::TyImplTrait(ref bounds) => {
@@ -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,
Oops, something went wrong.

0 comments on commit a167c04

Please sign in to comment.