Skip to content

Commit

Permalink
auto merge of #18743 : nikomatsakis/rust/hrtb-refactor-2, r=pcwalton
Browse files Browse the repository at this point in the history
Various miscellaneous changes pushing towards HRTB support:

1. Update parser and adjust ast to support `for<'a,'b>` syntax, both in closures and trait bounds. Warn on the old syntax (not error, for stage0).
2. Refactor TyTrait representation to include a TraitRef.
3. Purge `once_fns` feature gate and `once` keyword.

r? @pcwalton 

This is a [breaking-change]:

- The `once_fns` feature is now officially deprecated. Rewrite using normal closures or unboxed closures.
- The new `for`-based syntax now issues warnings (but not yet errors):
  - `fn<'a>(T) -> U` becomes `for<'a> fn(T) -> U`
  - `<'a> |T| -> U` becomes `for<'a> |T| -> U`
  • Loading branch information
bors committed Nov 9, 2014
2 parents 93c85eb + cf4e53e commit a2f303a
Show file tree
Hide file tree
Showing 52 changed files with 749 additions and 737 deletions.
4 changes: 2 additions & 2 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1690,8 +1690,8 @@ impl LintPass for Stability {
for t in supertraits.iter() {
match *t {
ast::TraitTyParamBound(ref t) => {
let id = ty::trait_ref_to_def_id(cx.tcx, t);
self.lint(cx, id, t.path.span);
let id = ty::trait_ref_to_def_id(cx.tcx, &t.trait_ref);
self.lint(cx, id, t.trait_ref.path.span);
}
_ => (/* pass */)
}
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,10 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
}
'x' => {
assert_eq!(next(st), '[');
let def = parse_def(st, NominalType, |x,y| conv(x,y));
let substs = parse_substs(st, |x,y| conv(x,y));
let trait_ref = parse_trait_ref(st, |x,y| conv(x,y));
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
assert_eq!(next(st), ']');
return ty::mk_trait(st.tcx, def, substs, bounds);
return ty::mk_trait(st.tcx, trait_ref, bounds);
}
'p' => {
let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
Expand Down
11 changes: 4 additions & 7 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,10 @@ fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
enc_substs(w, cx, substs);
mywrite!(w, "]");
}
ty::ty_trait(box ty::TyTrait {
def_id,
ref substs,
ref bounds
}) => {
mywrite!(w, "x[{}|", (cx.ds)(def_id));
enc_substs(w, cx, substs);
ty::ty_trait(box ty::TyTrait { ref principal,
ref bounds }) => {
mywrite!(w, "x[");
enc_trait_ref(w, cx, principal);
enc_existential_bounds(w, cx, bounds);
mywrite!(w, "]");
}
Expand Down
42 changes: 23 additions & 19 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,16 +1085,19 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
this.emit_enum_variant_arg(1, |this| idx.encode(this))
})
}
ty::UnsizeVtable(ty::TyTrait { def_id,
bounds: ref b,
ref substs },
ty::UnsizeVtable(ty::TyTrait { ref principal,
bounds: ref b },
self_ty) => {
this.emit_enum_variant("UnsizeVtable", 2, 4, |this| {
this.emit_enum_variant_arg(
0, |this| Ok(this.emit_existential_bounds(ecx, b)));
this.emit_enum_variant_arg(1, |this| def_id.encode(this));
this.emit_enum_variant_arg(2, |this| Ok(this.emit_ty(ecx, self_ty)));
this.emit_enum_variant_arg(3, |this| Ok(this.emit_substs(ecx, substs)))
this.emit_enum_variant_arg(0, |this| {
try!(this.emit_struct_field("principal", 0, |this| {
Ok(this.emit_trait_ref(ecx, &*principal))
}));
this.emit_struct_field("bounds", 1, |this| {
Ok(this.emit_existential_bounds(ecx, b))
})
});
this.emit_enum_variant_arg(1, |this| Ok(this.emit_ty(ecx, self_ty)))
})
}
}
Expand Down Expand Up @@ -1693,18 +1696,19 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
ty::UnsizeStruct(box uk, idx)
}
2 => {
let b =
this.read_enum_variant_arg(
0, |this| Ok(this.read_existential_bounds(dcx))).unwrap();
let def_id: ast::DefId =
this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
let ty_trait = try!(this.read_enum_variant_arg(0, |this| {
let principal = try!(this.read_struct_field("principal", 0, |this| {
Ok(this.read_trait_ref(dcx))
}));
Ok(ty::TyTrait {
principal: (*principal).clone(),
bounds: try!(this.read_struct_field("bounds", 1, |this| {
Ok(this.read_existential_bounds(dcx))
})),
})
}));
let self_ty =
this.read_enum_variant_arg(2, |this| Ok(this.read_ty(dcx))).unwrap();
let substs = this.read_enum_variant_arg(3,
|this| Ok(this.read_substs(dcx))).unwrap();
let ty_trait = ty::TyTrait { def_id: def_id.tr(dcx),
bounds: b,
substs: substs };
this.read_enum_variant_arg(1, |this| Ok(this.read_ty(dcx))).unwrap();
ty::UnsizeVtable(ty_trait, self_ty)
}
_ => panic!("bad enum variant for ty::UnsizeKind")
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
match *ty_param_bound {
ast::TraitTyParamBound(ref trait_ref) => {
if !self.tcx.sess.features.borrow().visible_private_types &&
self.path_is_private_type(trait_ref.ref_id) {
self.path_is_private_type(trait_ref.trait_ref.ref_id) {
self.tcx.sess.span_err(span,
"private type in exported type \
parameter bound");
Expand Down Expand Up @@ -1432,7 +1432,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
//
// Those in 2. are warned via walk_generics and this
// call here.
visit::walk_trait_ref_helper(self, tr)
self.visit_trait_ref(tr)
}
}
} else if trait_ref.is_none() && self_is_public_path {
Expand Down
30 changes: 23 additions & 7 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst};
use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
use syntax::ast::{PrimTy, Public, SelfExplicit, SelfStatic};
use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt};
use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyQPath};
use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyProc, TyQPath};
use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
use syntax::ast::{TypeImplItem, UnnamedField};
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
Expand Down Expand Up @@ -607,6 +607,7 @@ enum TraitReferenceType {
TraitImplementation, // impl SomeTrait for T { ... }
TraitDerivation, // trait T : SomeTrait { ... }
TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
TraitObject, // Box<for<'a> SomeTrait>
}

impl NameBindings {
Expand Down Expand Up @@ -4244,11 +4245,11 @@ impl<'a> Resolver<'a> {
this.resolve_type_parameter_bounds(item.id, bounds,
TraitDerivation);

match unbound {
&Some(ast::TraitTyParamBound(ref tpb)) => {
match *unbound {
Some(ref tpb) => {
this.resolve_trait_reference(item.id, tpb, TraitDerivation);
}
_ => {}
None => {}
}

for trait_item in (*trait_items).iter() {
Expand Down Expand Up @@ -4495,7 +4496,7 @@ impl<'a> Resolver<'a> {
}
match &type_parameter.unbound {
&Some(ref unbound) =>
self.resolve_type_parameter_bound(
self.resolve_trait_reference(
type_parameter.id, unbound, TraitBoundingTypeParameter),
&None => {}
}
Expand All @@ -4521,12 +4522,19 @@ impl<'a> Resolver<'a> {
reference_type: TraitReferenceType) {
match *type_parameter_bound {
TraitTyParamBound(ref tref) => {
self.resolve_trait_reference(id, tref, reference_type)
self.resolve_poly_trait_reference(id, tref, reference_type)
}
RegionTyParamBound(..) => {}
}
}

fn resolve_poly_trait_reference(&mut self,
id: NodeId,
poly_trait_reference: &PolyTraitRef,
reference_type: TraitReferenceType) {
self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
}

fn resolve_trait_reference(&mut self,
id: NodeId,
trait_reference: &TraitRef,
Expand All @@ -4538,6 +4546,7 @@ impl<'a> Resolver<'a> {
TraitBoundingTypeParameter => "bound type parameter with",
TraitImplementation => "implement",
TraitDerivation => "derive",
TraitObject => "reference",
};

let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
Expand Down Expand Up @@ -5044,6 +5053,13 @@ impl<'a> Resolver<'a> {
visit::walk_ty(self, ty);
}

TyPolyTraitRef(ref poly_trait_ref) => {
self.resolve_poly_trait_reference(
ty.id,
&**poly_trait_ref,
TraitObject);
visit::walk_ty(self, ty);
}
_ => {
// Just resolve embedded types.
visit::walk_ty(self, ty);
Expand Down
Loading

0 comments on commit a2f303a

Please sign in to comment.