Skip to content

Commit

Permalink
Auto merge of #39110 - petrochenkov:sum, r=eddyb
Browse files Browse the repository at this point in the history
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
bors committed Jan 17, 2017
2 parents 0825c96 + 66ef5f2 commit a167c04
Show file tree
Hide file tree
Showing 30 changed files with 239 additions and 373 deletions.
14 changes: 5 additions & 9 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
17 changes: 7 additions & 10 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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,
})
}
Expand Down
15 changes: 7 additions & 8 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>;
Expand Down Expand Up @@ -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),
Expand Down
14 changes: 6 additions & 8 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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)?;
}
}
}
Expand Down
11 changes: 5 additions & 6 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_incremental/calculate_svh/svh_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,6 @@ enum SawTyComponent {
SawTyTup,
SawTyPath,
SawTyObjectSum,
SawTyPolyTraitRef,
SawTyImplTrait,
SawTyTypeof,
SawTyInfer
Expand All @@ -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
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
_ => {}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
90 changes: 3 additions & 87 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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>)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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) => {
Expand Down
50 changes: 1 addition & 49 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit a167c04

Please sign in to comment.