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 https://github.com/rust-lang/rust/issues/39085#issuecomment-272743755 and https://github.com/rust-lang/rust/issues/39080 focused on data changes and mechanical renaming, I'll submit a PR with parser changes a bit later. r? @eddyb
This commit is contained in:
commit
a167c042ab
@ -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,
|
||||
|
@ -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);
|
||||
TyTraitObject(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),
|
||||
|
@ -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() {
|
||||
|
@ -204,11 +204,11 @@ pub struct AngleBracketedParameterData {
|
||||
/// The lifetime parameters for this path segment.
|
||||
pub lifetimes: Vec<Lifetime>,
|
||||
/// The type parameters for this path segment, if present.
|
||||
pub types: P<[P<Ty>]>,
|
||||
pub types: Vec<P<Ty>>,
|
||||
/// Bindings (equality constraints) on associated types, if present.
|
||||
///
|
||||
/// E.g., `Foo<A=Bar>`.
|
||||
pub bindings: P<[TypeBinding]>,
|
||||
pub bindings: Vec<TypeBinding>,
|
||||
}
|
||||
|
||||
impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
|
||||
@ -297,7 +297,7 @@ pub enum TraitBoundModifier {
|
||||
Maybe,
|
||||
}
|
||||
|
||||
pub type TyParamBounds = P<[TyParamBound]>;
|
||||
pub type TyParamBounds = Vec<TyParamBound>;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct TyParam {
|
||||
@ -314,7 +314,7 @@ pub struct TyParam {
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct Generics {
|
||||
pub lifetimes: Vec<LifetimeDef>,
|
||||
pub ty_params: P<[TyParam]>,
|
||||
pub ty_params: Vec<TyParam>,
|
||||
pub where_clause: WhereClause,
|
||||
pub span: Span,
|
||||
}
|
||||
@ -344,7 +344,7 @@ impl Default for Generics {
|
||||
fn default() -> Generics {
|
||||
Generics {
|
||||
lifetimes: Vec::new(),
|
||||
ty_params: P::new(),
|
||||
ty_params: Vec::new(),
|
||||
where_clause: WhereClause {
|
||||
id: DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
@ -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>,
|
||||
}
|
||||
|
||||
/// The set of MetaItems that define the compilation environment of the crate,
|
||||
@ -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.
|
||||
TraitObject(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>),
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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,
|
||||
@ -68,9 +67,6 @@ pub trait AstBuilder {
|
||||
fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
|
||||
fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
|
||||
|
||||
fn ty_vars(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> ;
|
||||
fn ty_vars_global(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> ;
|
||||
|
||||
fn typaram(&self,
|
||||
span: Span,
|
||||
id: ast::Ident,
|
||||
@ -334,8 +330,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
} else {
|
||||
Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
types: types,
|
||||
bindings: bindings,
|
||||
})))
|
||||
};
|
||||
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
|
||||
@ -370,8 +366,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
let mut path = trait_path;
|
||||
let parameters = ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
types: types,
|
||||
bindings: bindings,
|
||||
};
|
||||
path.segments.push(ast::PathSegment {
|
||||
identifier: ident,
|
||||
@ -403,12 +399,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)
|
||||
@ -465,20 +455,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// these are strange, and probably shouldn't be used outside of
|
||||
// pipes. Specifically, the global version possible generates
|
||||
// incorrect code.
|
||||
fn ty_vars(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> {
|
||||
ty_params.iter().map(|p| self.ty_ident(DUMMY_SP, p.ident)).collect()
|
||||
}
|
||||
|
||||
fn ty_vars_global(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> {
|
||||
ty_params
|
||||
.iter()
|
||||
.map(|p| self.ty_path(self.path_global(DUMMY_SP, vec![p.ident])))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
|
||||
ast::TraitRef {
|
||||
path: path,
|
||||
|
@ -540,7 +540,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
ExpansionKind::Expr => Expansion::Expr(self.parse_expr()?),
|
||||
ExpansionKind::OptExpr => Expansion::OptExpr(Some(self.parse_expr()?)),
|
||||
ExpansionKind::Ty => Expansion::Ty(self.parse_ty()?),
|
||||
ExpansionKind::Ty => Expansion::Ty(self.parse_ty_no_plus()?),
|
||||
ExpansionKind::Pat => Expansion::Pat(self.parse_pat()?),
|
||||
})
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ pub fn parse_arm_panic(parser: &mut Parser) -> Arm {
|
||||
}
|
||||
|
||||
pub fn parse_ty_panic(parser: &mut Parser) -> P<Ty> {
|
||||
panictry!(parser.parse_ty())
|
||||
panictry!(parser.parse_ty_no_plus())
|
||||
}
|
||||
|
||||
pub fn parse_stmt_panic(parser: &mut Parser) -> Option<Stmt> {
|
||||
|
@ -522,7 +522,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
|
||||
},
|
||||
"pat" => token::NtPat(panictry!(p.parse_pat())),
|
||||
"expr" => token::NtExpr(panictry!(p.parse_expr())),
|
||||
"ty" => token::NtTy(panictry!(p.parse_ty())),
|
||||
"ty" => token::NtTy(panictry!(p.parse_ty_no_plus())),
|
||||
// this could be handled like a token, since it is one
|
||||
"ident" => match p.token {
|
||||
token::Ident(sn) => {
|
||||
|
@ -225,7 +225,7 @@ pub trait Folder : Sized {
|
||||
noop_fold_ty_param(tp, self)
|
||||
}
|
||||
|
||||
fn fold_ty_params(&mut self, tps: P<[TyParam]>) -> P<[TyParam]> {
|
||||
fn fold_ty_params(&mut self, tps: Vec<TyParam>) -> Vec<TyParam> {
|
||||
noop_fold_ty_params(tps, self)
|
||||
}
|
||||
|
||||
@ -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::TraitObject(bounds) => {
|
||||
TyKind::TraitObject(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)))
|
||||
@ -678,8 +674,7 @@ pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_ty_params<T: Folder>(tps: P<[TyParam]>, fld: &mut T)
|
||||
-> P<[TyParam]> {
|
||||
pub fn noop_fold_ty_params<T: Folder>(tps: Vec<TyParam>, fld: &mut T) -> Vec<TyParam> {
|
||||
tps.move_map(|tp| fld.fold_ty_param(tp))
|
||||
}
|
||||
|
||||
@ -766,13 +761,13 @@ pub fn noop_fold_where_predicate<T: Folder>(
|
||||
})
|
||||
}
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
|
||||
path,
|
||||
ty,
|
||||
lhs_ty,
|
||||
rhs_ty,
|
||||
span}) => {
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{
|
||||
id: fld.new_id(id),
|
||||
path: fld.fold_path(path),
|
||||
ty:fld.fold_ty(ty),
|
||||
lhs_ty: fld.fold_ty(lhs_ty),
|
||||
rhs_ty: fld.fold_ty(rhs_ty),
|
||||
span: fld.new_span(span)
|
||||
})
|
||||
}
|
||||
|
@ -847,7 +847,7 @@ mod tests {
|
||||
Abi::Rust,
|
||||
ast::Generics{ // no idea on either of these:
|
||||
lifetimes: Vec::new(),
|
||||
ty_params: P::new(),
|
||||
ty_params: Vec::new(),
|
||||
where_clause: ast::WhereClause {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
|
@ -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;
|
||||
@ -685,7 +685,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
|
||||
sep: Option<token::Token>,
|
||||
mut f: F)
|
||||
-> PResult<'a, (P<[T]>, bool)>
|
||||
-> PResult<'a, (Vec<T>, bool)>
|
||||
where F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>,
|
||||
{
|
||||
let mut v = Vec::new();
|
||||
@ -706,7 +706,7 @@ impl<'a> Parser<'a> {
|
||||
if i % 2 == 0 {
|
||||
match f(self)? {
|
||||
Some(result) => v.push(result),
|
||||
None => return Ok((P::from_vec(v), true))
|
||||
None => return Ok((v, true))
|
||||
}
|
||||
} else {
|
||||
if let Some(t) = sep.as_ref() {
|
||||
@ -715,7 +715,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
}
|
||||
}
|
||||
return Ok((P::from_vec(v), false));
|
||||
return Ok((v, false));
|
||||
}
|
||||
|
||||
/// Parse a sequence bracketed by '<' and '>', stopping
|
||||
@ -723,7 +723,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_seq_to_before_gt<T, F>(&mut self,
|
||||
sep: Option<token::Token>,
|
||||
mut f: F)
|
||||
-> PResult<'a, P<[T]>> where
|
||||
-> PResult<'a, Vec<T>> where
|
||||
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
{
|
||||
let (result, returned) = self.parse_seq_to_before_gt_or_return(sep,
|
||||
@ -735,7 +735,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_seq_to_gt<T, F>(&mut self,
|
||||
sep: Option<token::Token>,
|
||||
f: F)
|
||||
-> PResult<'a, P<[T]>> where
|
||||
-> PResult<'a, Vec<T>> where
|
||||
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
{
|
||||
let v = self.parse_seq_to_before_gt(sep, f)?;
|
||||
@ -746,7 +746,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_seq_to_gt_or_return<T, F>(&mut self,
|
||||
sep: Option<token::Token>,
|
||||
f: F)
|
||||
-> PResult<'a, (P<[T]>, bool)> where
|
||||
-> PResult<'a, (Vec<T>, bool)> where
|
||||
F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>,
|
||||
{
|
||||
let (v, returned) = self.parse_seq_to_before_gt_or_return(sep, f)?;
|
||||
@ -1039,13 +1039,13 @@ impl<'a> Parser<'a> {
|
||||
let other_bounds = if self.eat(&token::BinOp(token::Plus)) {
|
||||
self.parse_ty_param_bounds()?
|
||||
} else {
|
||||
P::new()
|
||||
Vec::new()
|
||||
};
|
||||
let all_bounds =
|
||||
Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter()
|
||||
.chain(other_bounds.into_vec())
|
||||
.chain(other_bounds)
|
||||
.collect();
|
||||
Ok(ast::TyKind::PolyTraitRef(all_bounds))
|
||||
Ok(ast::TyKind::TraitObject(all_bounds))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1128,7 +1128,7 @@ impl<'a> Parser<'a> {
|
||||
self.expect_keyword(keywords::Const)?;
|
||||
let ident = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
let default = if self.check(&token::Eq) {
|
||||
self.bump();
|
||||
let expr = self.parse_expr()?;
|
||||
@ -1244,30 +1244,30 @@ impl<'a> Parser<'a> {
|
||||
/// Parse a possibly mutable type
|
||||
pub fn parse_mt(&mut self) -> PResult<'a, MutTy> {
|
||||
let mutbl = self.parse_mutability()?;
|
||||
let t = self.parse_ty()?;
|
||||
let t = self.parse_ty_no_plus()?;
|
||||
Ok(MutTy { ty: t, mutbl: mutbl })
|
||||
}
|
||||
|
||||
/// Parse optional return type [ -> TY ] in function decl
|
||||
pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> {
|
||||
if self.eat(&token::RArrow) {
|
||||
Ok(FunctionRetTy::Ty(self.parse_ty()?))
|
||||
Ok(FunctionRetTy::Ty(self.parse_ty_no_plus()?))
|
||||
} else {
|
||||
let pos = self.span.lo;
|
||||
Ok(FunctionRetTy::Default(mk_sp(pos, pos)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a type in a context where `T1+T2` is allowed.
|
||||
pub fn parse_ty_sum(&mut self) -> PResult<'a, P<Ty>> {
|
||||
/// Parse a type.
|
||||
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
||||
let lo = self.span.lo;
|
||||
let lhs = self.parse_ty()?;
|
||||
let lhs = self.parse_ty_no_plus()?;
|
||||
|
||||
if !self.eat(&token::BinOp(token::Plus)) {
|
||||
return Ok(lhs);
|
||||
}
|
||||
|
||||
let bounds = self.parse_ty_param_bounds()?;
|
||||
let mut bounds = self.parse_ty_param_bounds()?;
|
||||
|
||||
// In type grammar, `+` is treated like a binary operator,
|
||||
// and hence both L and R side are required.
|
||||
@ -1277,14 +1277,66 @@ 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::TraitObject(bounds);
|
||||
Ok(P(Ty {id: ast::DUMMY_NODE_ID, node: sum, span: sp}))
|
||||
}
|
||||
|
||||
/// Parse a type.
|
||||
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
||||
/// Parse a type in restricted contexts where `+` is not permitted.
|
||||
/// Example 1: `&'a TYPE`
|
||||
/// `+` is prohibited to maintain operator priority (P(+) < P(&)).
|
||||
/// Example 2: `value1 as TYPE + value2`
|
||||
/// `+` is prohibited to avoid interactions with expression grammar.
|
||||
pub fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
||||
maybe_whole!(self, NtTy, |x| x);
|
||||
|
||||
let lo = self.span.lo;
|
||||
@ -1298,7 +1350,7 @@ impl<'a> Parser<'a> {
|
||||
let mut ts = vec![];
|
||||
let mut last_comma = false;
|
||||
while self.token != token::CloseDelim(token::Paren) {
|
||||
ts.push(self.parse_ty_sum()?);
|
||||
ts.push(self.parse_ty()?);
|
||||
if self.check(&token::Comma) {
|
||||
last_comma = true;
|
||||
self.bump();
|
||||
@ -1323,7 +1375,7 @@ impl<'a> Parser<'a> {
|
||||
} else if self.check(&token::OpenDelim(token::Bracket)) {
|
||||
// VECTOR
|
||||
self.expect(&token::OpenDelim(token::Bracket))?;
|
||||
let t = self.parse_ty_sum()?;
|
||||
let t = self.parse_ty()?;
|
||||
|
||||
// Parse the `; e` in `[ i32; e ]`
|
||||
// where `e` is a const expression
|
||||
@ -1404,7 +1456,7 @@ impl<'a> Parser<'a> {
|
||||
`*mut T` or `*const T` as appropriate)");
|
||||
Mutability::Immutable
|
||||
};
|
||||
let t = self.parse_ty()?;
|
||||
let t = self.parse_ty_no_plus()?;
|
||||
Ok(MutTy { ty: t, mutbl: mutbl })
|
||||
}
|
||||
|
||||
@ -1451,7 +1503,7 @@ impl<'a> Parser<'a> {
|
||||
})
|
||||
};
|
||||
|
||||
let t = self.parse_ty_sum()?;
|
||||
let t = self.parse_ty()?;
|
||||
|
||||
Ok(Arg {
|
||||
ty: t,
|
||||
@ -1469,7 +1521,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
|
||||
let pat = self.parse_pat()?;
|
||||
let t = if self.eat(&token::Colon) {
|
||||
self.parse_ty_sum()?
|
||||
self.parse_ty()?
|
||||
} else {
|
||||
P(Ty {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
@ -1610,7 +1662,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn parse_qualified_path(&mut self, mode: PathStyle)
|
||||
-> PResult<'a, (QSelf, ast::Path)> {
|
||||
let span = self.prev_span;
|
||||
let self_type = self.parse_ty_sum()?;
|
||||
let self_type = self.parse_ty()?;
|
||||
let mut path = if self.eat_keyword(keywords::As) {
|
||||
self.parse_path(PathStyle::Type)?
|
||||
} else {
|
||||
@ -1711,8 +1763,8 @@ impl<'a> Parser<'a> {
|
||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
|
||||
ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
types: types,
|
||||
bindings: bindings,
|
||||
}.into()
|
||||
} else if self.eat(&token::OpenDelim(token::Paren)) {
|
||||
let lo = self.prev_span.lo;
|
||||
@ -1720,10 +1772,10 @@ impl<'a> Parser<'a> {
|
||||
let inputs = self.parse_seq_to_end(
|
||||
&token::CloseDelim(token::Paren),
|
||||
SeqSep::trailing_allowed(token::Comma),
|
||||
|p| p.parse_ty_sum())?;
|
||||
|p| p.parse_ty())?;
|
||||
|
||||
let output_ty = if self.eat(&token::RArrow) {
|
||||
Some(self.parse_ty()?)
|
||||
Some(self.parse_ty_no_plus()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -1771,8 +1823,8 @@ impl<'a> Parser<'a> {
|
||||
identifier: identifier,
|
||||
parameters: ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: P::from_vec(types),
|
||||
bindings: P::from_vec(bindings),
|
||||
types: types,
|
||||
bindings: bindings,
|
||||
}.into(),
|
||||
});
|
||||
|
||||
@ -2933,12 +2985,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
// Special cases:
|
||||
if op == AssocOp::As {
|
||||
let rhs = self.parse_ty()?;
|
||||
let rhs = self.parse_ty_no_plus()?;
|
||||
let (lo, hi) = (lhs_span.lo, rhs.span.hi);
|
||||
lhs = self.mk_expr(lo, hi, ExprKind::Cast(lhs, rhs), ThinVec::new());
|
||||
continue
|
||||
} else if op == AssocOp::Colon {
|
||||
let rhs = self.parse_ty()?;
|
||||
let rhs = self.parse_ty_no_plus()?;
|
||||
let (lo, hi) = (lhs_span.lo, rhs.span.hi);
|
||||
lhs = self.mk_expr(lo, hi, ExprKind::Type(lhs, rhs), ThinVec::new());
|
||||
continue
|
||||
@ -3706,7 +3758,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let mut ty = None;
|
||||
if self.eat(&token::Colon) {
|
||||
ty = Some(self.parse_ty_sum()?);
|
||||
ty = Some(self.parse_ty()?);
|
||||
}
|
||||
let init = self.parse_initializer()?;
|
||||
Ok(P(ast::Local {
|
||||
@ -3727,7 +3779,7 @@ impl<'a> Parser<'a> {
|
||||
-> PResult<'a, StructField> {
|
||||
let name = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
Ok(StructField {
|
||||
span: mk_sp(lo, self.prev_span.hi),
|
||||
ident: Some(name),
|
||||
@ -4144,7 +4196,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_colon_then_ty_param_bounds(&mut self) -> PResult<'a, TyParamBounds>
|
||||
{
|
||||
if !self.eat(&token::Colon) {
|
||||
Ok(P::new())
|
||||
Ok(Vec::new())
|
||||
} else {
|
||||
self.parse_ty_param_bounds()
|
||||
}
|
||||
@ -4190,7 +4242,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(P::from_vec(result));
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
|
||||
@ -4202,7 +4254,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let default = if self.check(&token::Eq) {
|
||||
self.bump();
|
||||
Some(self.parse_ty_sum()?)
|
||||
Some(self.parse_ty()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -4297,7 +4349,7 @@ impl<'a> Parser<'a> {
|
||||
let mut err = self.diagnostic().struct_span_err(self.span, &msg);
|
||||
|
||||
let span_hi = self.span.hi;
|
||||
let span_hi = match self.parse_ty() {
|
||||
let span_hi = match self.parse_ty_no_plus() {
|
||||
Ok(..) => self.span.hi,
|
||||
Err(ref mut err) => {
|
||||
self.cancel(err);
|
||||
@ -4320,14 +4372,14 @@ impl<'a> Parser<'a> {
|
||||
if p.look_ahead(1, |t| t == &token::Eq) {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(p.parse_ty_sum()?))
|
||||
Ok(Some(p.parse_ty()?))
|
||||
}
|
||||
}
|
||||
)?;
|
||||
|
||||
// If we found the `>`, don't continue.
|
||||
if !returned {
|
||||
return Ok((lifetimes, types.into_vec(), Vec::new()));
|
||||
return Ok((lifetimes, types, Vec::new()));
|
||||
}
|
||||
|
||||
// Then parse type bindings.
|
||||
@ -4338,7 +4390,7 @@ impl<'a> Parser<'a> {
|
||||
let lo = p.span.lo;
|
||||
let ident = p.parse_ident()?;
|
||||
p.expect(&token::Eq)?;
|
||||
let ty = p.parse_ty()?;
|
||||
let ty = p.parse_ty_no_plus()?;
|
||||
let hi = ty.span.hi;
|
||||
let span = mk_sp(lo, hi);
|
||||
return Ok(TypeBinding{id: ast::DUMMY_NODE_ID,
|
||||
@ -4348,7 +4400,7 @@ impl<'a> Parser<'a> {
|
||||
});
|
||||
}
|
||||
)?;
|
||||
Ok((lifetimes, types.into_vec(), bindings.into_vec()))
|
||||
Ok((lifetimes, types, bindings))
|
||||
}
|
||||
|
||||
fn forbid_lifetime(&mut self) -> PResult<'a, ()> {
|
||||
@ -4436,7 +4488,7 @@ impl<'a> Parser<'a> {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let bounded_ty = self.parse_ty()?;
|
||||
let bounded_ty = self.parse_ty_no_plus()?;
|
||||
|
||||
if self.eat(&token::Colon) {
|
||||
let bounds = self.parse_ty_param_bounds()?;
|
||||
@ -4459,7 +4511,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
parsed_something = true;
|
||||
} else if self.eat(&token::Eq) {
|
||||
// let ty = try!(self.parse_ty());
|
||||
// let ty = try!(self.parse_ty_no_plus());
|
||||
let hi = self.prev_span.hi;
|
||||
let span = mk_sp(lo, hi);
|
||||
// where_clause.predicates.push(
|
||||
@ -4631,7 +4683,7 @@ impl<'a> Parser<'a> {
|
||||
// self: TYPE
|
||||
let eself_ident = expect_ident(self);
|
||||
if self.eat(&token::Colon) {
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
(SelfKind::Explicit(ty, Mutability::Immutable), eself_ident)
|
||||
} else {
|
||||
(SelfKind::Value(Mutability::Immutable), eself_ident)
|
||||
@ -4643,7 +4695,7 @@ impl<'a> Parser<'a> {
|
||||
self.bump();
|
||||
let eself_ident = expect_ident(self);
|
||||
if self.eat(&token::Colon) {
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
(SelfKind::Explicit(ty, Mutability::Mutable), eself_ident)
|
||||
} else {
|
||||
(SelfKind::Value(Mutability::Mutable), eself_ident)
|
||||
@ -4800,14 +4852,14 @@ impl<'a> Parser<'a> {
|
||||
let (name, node) = if self.eat_keyword(keywords::Type) {
|
||||
let name = self.parse_ident()?;
|
||||
self.expect(&token::Eq)?;
|
||||
let typ = self.parse_ty_sum()?;
|
||||
let typ = self.parse_ty()?;
|
||||
self.expect(&token::Semi)?;
|
||||
(name, ast::ImplItemKind::Type(typ))
|
||||
} else if self.is_const_item() {
|
||||
self.expect_keyword(keywords::Const)?;
|
||||
let name = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let typ = self.parse_ty_sum()?;
|
||||
let typ = self.parse_ty()?;
|
||||
self.expect(&token::Eq)?;
|
||||
let expr = self.parse_expr()?;
|
||||
self.expect(&token::Semi)?;
|
||||
@ -4931,7 +4983,7 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
|
||||
// Parse the trait.
|
||||
let mut ty = self.parse_ty_sum()?;
|
||||
let mut ty = self.parse_ty()?;
|
||||
|
||||
// Parse traits, if necessary.
|
||||
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
|
||||
@ -4972,7 +5024,7 @@ impl<'a> Parser<'a> {
|
||||
ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None))
|
||||
} else {
|
||||
if opt_trait.is_some() {
|
||||
ty = self.parse_ty_sum()?;
|
||||
ty = self.parse_ty()?;
|
||||
}
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
|
||||
@ -5124,7 +5176,7 @@ impl<'a> Parser<'a> {
|
||||
let mut vis = p.parse_visibility(false)?;
|
||||
let ty_is_interpolated =
|
||||
p.token.is_interpolated() || p.look_ahead(1, |t| t.is_interpolated());
|
||||
let mut ty = p.parse_ty_sum()?;
|
||||
let mut ty = p.parse_ty()?;
|
||||
|
||||
// Handle `pub(path) type`, in which `vis` will be `pub` and `ty` will be `(path)`.
|
||||
if vis == Visibility::Public && !ty_is_interpolated &&
|
||||
@ -5132,7 +5184,7 @@ impl<'a> Parser<'a> {
|
||||
ty = if let TyKind::Paren(ref path_ty) = ty.node {
|
||||
if let TyKind::Path(None, ref path) = path_ty.node {
|
||||
vis = Visibility::Restricted { path: P(path.clone()), id: path_ty.id };
|
||||
Some(p.parse_ty_sum()?)
|
||||
Some(p.parse_ty()?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -5250,7 +5302,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
|
||||
let id = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
self.expect(&token::Eq)?;
|
||||
let e = self.parse_expr()?;
|
||||
self.expect(&token::Semi)?;
|
||||
@ -5491,7 +5543,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let ident = self.parse_ident()?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
let hi = self.span.hi;
|
||||
self.expect(&token::Semi)?;
|
||||
Ok(ForeignItem {
|
||||
@ -5580,7 +5632,7 @@ impl<'a> Parser<'a> {
|
||||
let mut tps = self.parse_generics()?;
|
||||
tps.where_clause = self.parse_where_clause()?;
|
||||
self.expect(&token::Eq)?;
|
||||
let ty = self.parse_ty_sum()?;
|
||||
let ty = self.parse_ty()?;
|
||||
self.expect(&token::Semi)?;
|
||||
Ok((ident, ItemKind::Ty(ty, tps), None))
|
||||
}
|
||||
|
@ -1009,7 +1009,7 @@ impl<'a> State<'a> {
|
||||
ast::TyKind::BareFn(ref f) => {
|
||||
let generics = ast::Generics {
|
||||
lifetimes: f.lifetimes.clone(),
|
||||
ty_params: P::new(),
|
||||
ty_params: Vec::new(),
|
||||
where_clause: ast::WhereClause {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
@ -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::TraitObject(ref bounds) => {
|
||||
self.print_bounds("", &bounds[..])?;
|
||||
}
|
||||
ast::TyKind::ImplTrait(ref bounds) => {
|
||||
@ -2849,11 +2845,13 @@ impl<'a> State<'a> {
|
||||
..}) => {
|
||||
self.print_lifetime_bounds(lifetime, bounds)?;
|
||||
}
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
|
||||
self.print_path(path, false, 0, false)?;
|
||||
ast::WherePredicate::EqPredicate(ast::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)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2975,7 +2973,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
let generics = ast::Generics {
|
||||
lifetimes: Vec::new(),
|
||||
ty_params: P::new(),
|
||||
ty_params: Vec::new(),
|
||||
where_clause: ast::WhereClause {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
|
@ -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::TraitObject(ref bounds) => {
|
||||
walk_list!(visitor, visit_ty_param_bound, bounds);
|
||||
}
|
||||
TyKind::ImplTrait(ref bounds) => {
|
||||
@ -508,12 +504,11 @@ pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics
|
||||
visitor.visit_lifetime(lifetime);
|
||||
walk_list!(visitor, visit_lifetime, bounds);
|
||||
}
|
||||
WherePredicate::EqPredicate(WhereEqPredicate{id,
|
||||
ref path,
|
||||
ref ty,
|
||||
WherePredicate::EqPredicate(WhereEqPredicate{ref lhs_ty,
|
||||
ref rhs_ty,
|
||||
..}) => {
|
||||
visitor.visit_path(path, id);
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_ty(lhs_ty);
|
||||
visitor.visit_ty(rhs_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -507,9 +507,8 @@ impl<'a> TraitDef<'a> {
|
||||
}
|
||||
});
|
||||
|
||||
let Generics { mut lifetimes, ty_params, mut where_clause, span } = self.generics
|
||||
let Generics { mut lifetimes, mut ty_params, mut where_clause, span } = self.generics
|
||||
.to_generics(cx, self.span, type_ident, generics);
|
||||
let mut ty_params = ty_params.into_vec();
|
||||
|
||||
// Copy the lifetimes
|
||||
lifetimes.extend(generics.lifetimes.iter().cloned());
|
||||
@ -533,7 +532,7 @@ impl<'a> TraitDef<'a> {
|
||||
bounds.push((*declared_bound).clone());
|
||||
}
|
||||
|
||||
cx.typaram(self.span, ty_param.ident, vec![], P::from_vec(bounds), None)
|
||||
cx.typaram(self.span, ty_param.ident, vec![], bounds, None)
|
||||
}));
|
||||
|
||||
// and similarly for where clauses
|
||||
@ -558,8 +557,8 @@ impl<'a> TraitDef<'a> {
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
path: we.path.clone(),
|
||||
ty: we.ty.clone(),
|
||||
lhs_ty: we.lhs_ty.clone(),
|
||||
rhs_ty: we.rhs_ty.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -596,7 +595,7 @@ impl<'a> TraitDef<'a> {
|
||||
span: self.span,
|
||||
bound_lifetimes: vec![],
|
||||
bounded_ty: ty,
|
||||
bounds: P::from_vec(bounds),
|
||||
bounds: bounds,
|
||||
};
|
||||
|
||||
let predicate = ast::WherePredicate::BoundPredicate(predicate);
|
||||
@ -607,7 +606,7 @@ impl<'a> TraitDef<'a> {
|
||||
|
||||
let trait_generics = Generics {
|
||||
lifetimes: lifetimes,
|
||||
ty_params: P::from_vec(ty_params),
|
||||
ty_params: ty_params,
|
||||
where_clause: where_clause,
|
||||
span: span,
|
||||
};
|
||||
|
@ -212,7 +212,7 @@ fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>, s
|
||||
-> Generics {
|
||||
Generics {
|
||||
lifetimes: lifetimes,
|
||||
ty_params: P::from_vec(ty_params),
|
||||
ty_params: ty_params,
|
||||
where_clause: ast::WhereClause {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
|
@ -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() {
|
||||
}
|
@ -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() {
|
||||
|
@ -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() { }
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user