Skip to content

Commit

Permalink
AST/HIR: Merge ObjectSum and PolyTraitRef
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Jan 16, 2017
1 parent 8284046 commit 2efe865
Show file tree
Hide file tree
Showing 22 changed files with 119 additions and 240 deletions.
6 changes: 1 addition & 5 deletions src/librustc/hir/intravisit.rs
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) => {
TyObjectSum(ref bounds) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
TyImplTrait(ref bounds) => {
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/hir/lowering.rs
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::ObjectSum(ref bounds) => {
hir::TyObjectSum(self.lower_bounds(bounds))
}
TyKind::ImplTrait(ref bounds) => {
hir::TyImplTrait(self.lower_bounds(bounds))
Expand Down
11 changes: 5 additions & 6 deletions src/librustc/hir/mod.rs
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.
TyObjectSum(TyParamBounds),
/// An `impl Bound1 + Bound2 + Bound3` type
/// where `Bound` is a trait or a lifetime.
TyImplTrait(TyParamBounds),
/// Unused for now
TyTypeof(BodyId),
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/hir/print.rs
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::TyObjectSum(ref bounds) => {
self.print_bounds("", &bounds[..])?;
}
hir::TyImplTrait(ref bounds) => {
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_incremental/calculate_svh/svh_visitor.rs
Expand Up @@ -441,7 +441,6 @@ enum SawTyComponent {
SawTyTup,
SawTyPath,
SawTyObjectSum,
SawTyPolyTraitRef,
SawTyImplTrait,
SawTyTypeof,
SawTyInfer
Expand All @@ -458,7 +457,6 @@ fn saw_ty(node: &Ty_) -> SawTyComponent {
TyTup(..) => SawTyTup,
TyPath(_) => SawTyPath,
TyObjectSum(..) => SawTyObjectSum,
TyPolyTraitRef(..) => SawTyPolyTraitRef,
TyImplTrait(..) => SawTyImplTrait,
TyTypeof(..) => SawTyTypeof,
TyInfer => SawTyInfer
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_passes/ast_validation.rs
Expand Up @@ -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);
}
_ => {}
Expand Down
88 changes: 2 additions & 86 deletions src/librustc_typeck/astconv.rs
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 @@ -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::TyObjectSum(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
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
29 changes: 14 additions & 15 deletions src/librustdoc/clean/mod.rs
Expand Up @@ -1504,9 +1504,6 @@ pub enum Type {
// _
Infer,

// for<'a> Foo(&'a)
PolyTraitRef(Vec<TyParamBound>),

// impl TraitA+TraitB
ImplTrait(Vec<TyParamBound>),
}
Expand Down Expand Up @@ -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),
Expand Down
13 changes: 0 additions & 13 deletions src/librustdoc/html/format.rs
Expand Up @@ -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() {
Expand Down
10 changes: 5 additions & 5 deletions src/libsyntax/ast.rs
Expand Up @@ -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>),
Expand Down
22 changes: 22 additions & 0 deletions src/libsyntax/diagnostic_list.rs
Expand Up @@ -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.
Expand Down

0 comments on commit 2efe865

Please sign in to comment.