Accept ?Sized
as well as Sized?
Includes a bit of refactoring to store `?` unbounds as bounds with a modifier, rather than in their own world, in the AST at least.
This commit is contained in:
parent
5ba6102657
commit
e656081b70
26 changed files with 179 additions and 138 deletions
|
@ -1782,9 +1782,9 @@ impl LintPass for Stability {
|
|||
if self.is_internal(cx, item.span) { return }
|
||||
|
||||
match item.node {
|
||||
ast::ItemTrait(_, _, _, ref supertraits, _) => {
|
||||
ast::ItemTrait(_, _, ref supertraits, _) => {
|
||||
for t in supertraits.iter() {
|
||||
if let ast::TraitTyParamBound(ref t) = *t {
|
||||
if let ast::TraitTyParamBound(ref t, _) = *t {
|
||||
let id = ty::trait_ref_to_def_id(cx.tcx, &t.trait_ref);
|
||||
self.lint(cx, id, t.trait_ref.path.span);
|
||||
}
|
||||
|
|
|
@ -1308,7 +1308,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::ItemTrait(_, _, _, _, ref ms) => {
|
||||
ast::ItemTrait(_, _, _, ref ms) => {
|
||||
add_to_index(item, rbml_w, index);
|
||||
rbml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(rbml_w, def_id);
|
||||
|
|
|
@ -1043,7 +1043,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
ident: ty_param.ident,
|
||||
id: ty_param.id,
|
||||
bounds: bounds,
|
||||
unbound: ty_param.unbound.clone(),
|
||||
default: ty_param.default.clone(),
|
||||
span: ty_param.span,
|
||||
}
|
||||
|
@ -1063,7 +1062,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
// be passing down a map.
|
||||
ast::RegionTyParamBound(lt)
|
||||
}
|
||||
&ast::TraitTyParamBound(ref poly_tr) => {
|
||||
&ast::TraitTyParamBound(ref poly_tr, modifier) => {
|
||||
let tr = &poly_tr.trait_ref;
|
||||
let last_seg = tr.path.segments.last().unwrap();
|
||||
let mut insert = Vec::new();
|
||||
|
@ -1087,7 +1086,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
path: new_path,
|
||||
ref_id: tr.ref_id,
|
||||
}
|
||||
})
|
||||
}, modifier)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -122,7 +122,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
|
|||
// method to the root. In this case, if the trait is private, then
|
||||
// parent all the methods to the trait to indicate that they're
|
||||
// private.
|
||||
ast::ItemTrait(_, _, _, _, ref methods) if item.vis != ast::Public => {
|
||||
ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
|
||||
for m in methods.iter() {
|
||||
match *m {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
|
@ -328,7 +328,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
|
||||
// Default methods on traits are all public so long as the trait
|
||||
// is public
|
||||
ast::ItemTrait(_, _, _, _, ref methods) if public_first => {
|
||||
ast::ItemTrait(_, _, _, ref methods) if public_first => {
|
||||
for method in methods.iter() {
|
||||
match *method {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
|
@ -1178,7 +1178,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ast::ItemTrait(_, _, _, _, ref methods) => {
|
||||
ast::ItemTrait(_, _, _, ref methods) => {
|
||||
for m in methods.iter() {
|
||||
match *m {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
|
@ -1242,7 +1242,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
|
||||
ast::ItemStruct(ref def, _) => check_struct(&**def),
|
||||
|
||||
ast::ItemTrait(_, _, _, _, ref methods) => {
|
||||
ast::ItemTrait(_, _, _, ref methods) => {
|
||||
for m in methods.iter() {
|
||||
match *m {
|
||||
ast::RequiredMethod(..) => {}
|
||||
|
@ -1306,7 +1306,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
|
||||
fn check_ty_param_bound(&self,
|
||||
ty_param_bound: &ast::TyParamBound) {
|
||||
if let ast::TraitTyParamBound(ref trait_ref) = *ty_param_bound {
|
||||
if let ast::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound {
|
||||
if !self.tcx.sess.features.borrow().visible_private_types &&
|
||||
self.path_is_private_type(trait_ref.trait_ref.ref_id) {
|
||||
let span = trait_ref.trait_ref.path.span;
|
||||
|
@ -1349,7 +1349,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
// namespace (the contents have their own privacies).
|
||||
ast::ItemForeignMod(_) => {}
|
||||
|
||||
ast::ItemTrait(_, _, _, ref bounds, _) => {
|
||||
ast::ItemTrait(_, _, ref bounds, _) => {
|
||||
if !self.trait_is_public(item.id) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
ast::ItemTy(_, ref generics) |
|
||||
ast::ItemEnum(_, ref generics) |
|
||||
ast::ItemStruct(_, ref generics) |
|
||||
ast::ItemTrait(_, ref generics, _, _, _) |
|
||||
ast::ItemTrait(_, ref generics, _, _) |
|
||||
ast::ItemImpl(_, ref generics, _, _, _) => {
|
||||
// These kinds of items have only early bound lifetime parameters.
|
||||
let lifetimes = &generics.lifetimes;
|
||||
|
@ -232,7 +232,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, trait_ref: &ast::PolyTraitRef) {
|
||||
fn visit_poly_trait_ref(&mut self, trait_ref:
|
||||
&ast::PolyTraitRef,
|
||||
_modifier: &ast::TraitBoundModifier) {
|
||||
debug!("visit_poly_trait_ref trait_ref={}", trait_ref);
|
||||
|
||||
self.with(LateScope(&trait_ref.bound_lifetimes, self.scope), |old_scope, this| {
|
||||
|
|
|
@ -4608,7 +4608,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
|||
match cx.map.find(id.node) {
|
||||
Some(ast_map::NodeItem(item)) => {
|
||||
match item.node {
|
||||
ItemTrait(_, _, _, _, ref ms) => {
|
||||
ItemTrait(_, _, _, ref ms) => {
|
||||
let (_, p) =
|
||||
ast_util::split_trait_methods(ms[]);
|
||||
p.iter()
|
||||
|
|
|
@ -1459,7 +1459,7 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
ItemImpl(_, _, Some(_), _, _) => parent,
|
||||
|
||||
ItemTrait(_, _, _, _, ref items) => {
|
||||
ItemTrait(_, _, _, ref items) => {
|
||||
let name_bindings =
|
||||
self.add_child(name,
|
||||
parent.clone(),
|
||||
|
@ -3998,7 +3998,7 @@ impl<'a> Resolver<'a> {
|
|||
impl_items[]);
|
||||
}
|
||||
|
||||
ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
|
||||
ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
|
||||
// Create a new rib for the self type.
|
||||
let mut self_type_rib = Rib::new(ItemRibKind);
|
||||
|
||||
|
@ -4019,13 +4019,6 @@ impl<'a> Resolver<'a> {
|
|||
this.resolve_type_parameter_bounds(item.id, bounds,
|
||||
TraitDerivation);
|
||||
|
||||
match *unbound {
|
||||
Some(ref tpb) => {
|
||||
this.resolve_trait_reference(item.id, tpb, TraitDerivation);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
for trait_item in (*trait_items).iter() {
|
||||
// Create a new rib for the trait_item-specific type
|
||||
// parameters.
|
||||
|
@ -4273,12 +4266,6 @@ impl<'a> Resolver<'a> {
|
|||
self.resolve_type_parameter_bound(type_parameter.id, bound,
|
||||
TraitBoundingTypeParameter);
|
||||
}
|
||||
match &type_parameter.unbound {
|
||||
&Some(ref unbound) =>
|
||||
self.resolve_trait_reference(
|
||||
type_parameter.id, unbound, TraitBoundingTypeParameter),
|
||||
&None => {}
|
||||
}
|
||||
match type_parameter.default {
|
||||
Some(ref ty) => self.resolve_type(&**ty),
|
||||
None => {}
|
||||
|
@ -4300,7 +4287,7 @@ impl<'a> Resolver<'a> {
|
|||
type_parameter_bound: &TyParamBound,
|
||||
reference_type: TraitReferenceType) {
|
||||
match *type_parameter_bound {
|
||||
TraitTyParamBound(ref tref) => {
|
||||
TraitTyParamBound(ref tref, _) => {
|
||||
self.resolve_poly_trait_reference(id, tref, reference_type)
|
||||
}
|
||||
RegionTyParamBound(..) => {}
|
||||
|
|
|
@ -710,7 +710,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
// super-traits
|
||||
for super_bound in trait_refs.iter() {
|
||||
let trait_ref = match *super_bound {
|
||||
ast::TraitTyParamBound(ref trait_ref) => {
|
||||
ast::TraitTyParamBound(ref trait_ref, _) => {
|
||||
trait_ref
|
||||
}
|
||||
ast::RegionTyParamBound(..) => {
|
||||
|
@ -1052,7 +1052,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
&**typ,
|
||||
impl_items)
|
||||
}
|
||||
ast::ItemTrait(_, ref generics, _, ref trait_refs, ref methods) =>
|
||||
ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) =>
|
||||
self.process_trait(item, generics, trait_refs, methods),
|
||||
ast::ItemMod(ref m) => self.process_mod(item, m),
|
||||
ast::ItemTy(ref ty, ref ty_params) => {
|
||||
|
@ -1076,7 +1076,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
fn visit_generics(&mut self, generics: &ast::Generics) {
|
||||
for param in generics.ty_params.iter() {
|
||||
for bound in param.bounds.iter() {
|
||||
if let ast::TraitTyParamBound(ref trait_ref) = *bound {
|
||||
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
|
||||
self.process_trait_ref(&trait_ref.trait_ref, None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1625,7 +1625,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
|
|||
let mut trait_def_ids = DefIdMap::new();
|
||||
for ast_bound in ast_bounds.iter() {
|
||||
match *ast_bound {
|
||||
ast::TraitTyParamBound(ref b) => {
|
||||
ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => {
|
||||
match ::lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
|
||||
def::DefTrait(trait_did) => {
|
||||
match trait_def_ids.get(&trait_did) {
|
||||
|
@ -1663,6 +1663,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
|
|||
}
|
||||
trait_bounds.push(b);
|
||||
}
|
||||
ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) => {}
|
||||
ast::RegionTyParamBound(ref l) => {
|
||||
region_bounds.push(l);
|
||||
}
|
||||
|
|
|
@ -658,7 +658,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
}
|
||||
|
||||
}
|
||||
ast::ItemTrait(_, _, _, _, ref trait_methods) => {
|
||||
ast::ItemTrait(_, _, _, ref trait_methods) => {
|
||||
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
|
||||
for trait_method in trait_methods.iter() {
|
||||
match *trait_method {
|
||||
|
|
|
@ -259,7 +259,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
trait_def: &ty::TraitDef<'tcx>) {
|
||||
let tcx = ccx.tcx;
|
||||
if let ast_map::NodeItem(item) = tcx.map.get(trait_id) {
|
||||
if let ast::ItemTrait(_, _, _, _, ref trait_items) = item.node {
|
||||
if let ast::ItemTrait(_, _, _, ref trait_items) = item.node {
|
||||
// For each method, construct a suitable ty::Method and
|
||||
// store it into the `tcx.impl_or_trait_items` table:
|
||||
for trait_item in trait_items.iter() {
|
||||
|
@ -627,11 +627,6 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
|
|||
ast::RegionTyParamBound(..) => { }
|
||||
}
|
||||
}
|
||||
|
||||
match ty_param.unbound {
|
||||
Some(_) => { warn = true; }
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
|
||||
if warn {
|
||||
|
@ -1146,7 +1141,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
AllowEqConstraints::DontAllow);
|
||||
}
|
||||
},
|
||||
ast::ItemTrait(_, _, _, _, ref trait_methods) => {
|
||||
ast::ItemTrait(_, _, _, ref trait_methods) => {
|
||||
let trait_def = trait_def_of_item(ccx, it);
|
||||
|
||||
debug!("trait_def: ident={} trait_def={}",
|
||||
|
@ -1338,13 +1333,12 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
return def.clone();
|
||||
}
|
||||
|
||||
let (unsafety, generics, unbound, bounds, items) = match it.node {
|
||||
let (unsafety, generics, bounds, items) = match it.node {
|
||||
ast::ItemTrait(unsafety,
|
||||
ref generics,
|
||||
ref unbound,
|
||||
ref supertraits,
|
||||
ref items) => {
|
||||
(unsafety, generics, unbound, supertraits, items.as_slice())
|
||||
(unsafety, generics, supertraits, items.as_slice())
|
||||
}
|
||||
ref s => {
|
||||
tcx.sess.span_bug(
|
||||
|
@ -1367,7 +1361,6 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
token::SELF_KEYWORD_NAME,
|
||||
self_param_ty,
|
||||
bounds.as_slice(),
|
||||
unbound,
|
||||
it.span);
|
||||
|
||||
let substs = mk_item_substs(ccx, &ty_generics);
|
||||
|
@ -1683,29 +1676,37 @@ fn ty_generics_for_fn_or_method<'tcx,AC>(
|
|||
create_type_parameters_for_associated_types)
|
||||
}
|
||||
|
||||
// Add the Sized bound, unless the type parameter is marked as `Sized?`.
|
||||
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
|
||||
fn add_unsized_bound<'tcx,AC>(this: &AC,
|
||||
unbound: &Option<ast::TraitRef>,
|
||||
bounds: &mut ty::BuiltinBounds,
|
||||
desc: &str,
|
||||
ast_bounds: &[ast::TyParamBound],
|
||||
span: Span)
|
||||
where AC: AstConv<'tcx> {
|
||||
// Try to find an unbound in bounds.
|
||||
let mut unbound = None;
|
||||
for ab in ast_bounds.iter() {
|
||||
if let &ast::TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = ab {
|
||||
if unbound.is_none() {
|
||||
assert!(ptr.bound_lifetimes.is_empty());
|
||||
unbound = Some(ptr.trait_ref.clone());
|
||||
} else {
|
||||
this.tcx().sess.span_err(span, "type parameter has more than one relaxed default \
|
||||
bound, only one is supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let kind_id = this.tcx().lang_items.require(SizedTraitLangItem);
|
||||
match unbound {
|
||||
&Some(ref tpb) => {
|
||||
Some(ref tpb) => {
|
||||
// FIXME(#8559) currently requires the unbound to be built-in.
|
||||
let trait_def_id = ty::trait_ref_to_def_id(this.tcx(), tpb);
|
||||
match kind_id {
|
||||
Ok(kind_id) if trait_def_id != kind_id => {
|
||||
this.tcx().sess.span_warn(span,
|
||||
format!("default bound relaxed \
|
||||
for a {}, but this \
|
||||
does nothing because \
|
||||
the given bound is not \
|
||||
a default. \
|
||||
Only `Sized?` is \
|
||||
supported",
|
||||
desc)[]);
|
||||
"default bound relaxed for a type parameter, but \
|
||||
this does nothing because the given bound is not \
|
||||
a default. Only `?Sized` is supported");
|
||||
ty::try_add_builtin_trait(this.tcx(),
|
||||
kind_id,
|
||||
bounds);
|
||||
|
@ -1717,7 +1718,7 @@ fn add_unsized_bound<'tcx,AC>(this: &AC,
|
|||
ty::try_add_builtin_trait(this.tcx(), kind_id.unwrap(), bounds);
|
||||
}
|
||||
// No lang item for Sized, so we can't add it as a bound.
|
||||
&None => {}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1807,7 +1808,7 @@ fn ty_generics<'tcx,AC>(this: &AC,
|
|||
|
||||
for bound in bound_pred.bounds.iter() {
|
||||
match bound {
|
||||
&ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref) => {
|
||||
&ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
|
||||
let trait_ref = astconv::instantiate_poly_trait_ref(
|
||||
this,
|
||||
&ExplicitRscope,
|
||||
|
@ -1880,7 +1881,7 @@ fn ty_generics<'tcx,AC>(this: &AC,
|
|||
for bound in param.bounds.iter() {
|
||||
// In the above example, `ast_trait_ref` is `Iterator`.
|
||||
let ast_trait_ref = match *bound {
|
||||
ast::TraitTyParamBound(ref r) => r,
|
||||
ast::TraitTyParamBound(ref r, _) => r,
|
||||
ast::RegionTyParamBound(..) => { continue; }
|
||||
};
|
||||
|
||||
|
@ -1978,7 +1979,6 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
|
|||
param.ident.name,
|
||||
param_ty,
|
||||
param.bounds[],
|
||||
¶m.unbound,
|
||||
param.span);
|
||||
let default = match param.default {
|
||||
None => None,
|
||||
|
@ -2023,7 +2023,6 @@ fn compute_bounds<'tcx,AC>(this: &AC,
|
|||
name_of_bounded_thing: ast::Name,
|
||||
param_ty: ty::ParamTy,
|
||||
ast_bounds: &[ast::TyParamBound],
|
||||
unbound: &Option<ast::TraitRef>,
|
||||
span: Span)
|
||||
-> ty::ParamBounds<'tcx>
|
||||
where AC: AstConv<'tcx> {
|
||||
|
@ -2032,11 +2031,9 @@ fn compute_bounds<'tcx,AC>(this: &AC,
|
|||
param_ty,
|
||||
ast_bounds);
|
||||
|
||||
|
||||
add_unsized_bound(this,
|
||||
unbound,
|
||||
&mut param_bounds.builtin_bounds,
|
||||
"type parameter",
|
||||
ast_bounds,
|
||||
span);
|
||||
|
||||
check_bounds_compatible(this.tcx(),
|
||||
|
|
|
@ -353,7 +353,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
|||
match item.node {
|
||||
ast::ItemEnum(_, ref generics) |
|
||||
ast::ItemStruct(_, ref generics) |
|
||||
ast::ItemTrait(_, ref generics, _, _, _) => {
|
||||
ast::ItemTrait(_, ref generics, _, _) => {
|
||||
for (i, p) in generics.lifetimes.iter().enumerate() {
|
||||
let id = p.lifetime.id;
|
||||
self.add_inferred(item.id, RegionParam, TypeSpace, i, id);
|
||||
|
|
|
@ -371,10 +371,18 @@ pub const DUMMY_NODE_ID: NodeId = -1;
|
|||
/// detects Copy, Send and Sync.
|
||||
#[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub enum TyParamBound {
|
||||
TraitTyParamBound(PolyTraitRef),
|
||||
TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
|
||||
RegionTyParamBound(Lifetime)
|
||||
}
|
||||
|
||||
/// A modifier on a bound, currently this is only used for `?Sized`, where the
|
||||
/// modifier is `Maybe`. Negative bounds should also be handled here.
|
||||
#[deriving(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub enum TraitBoundModifier {
|
||||
None,
|
||||
Maybe,
|
||||
}
|
||||
|
||||
pub type TyParamBounds = OwnedSlice<TyParamBound>;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
|
@ -382,7 +390,6 @@ pub struct TyParam {
|
|||
pub ident: Ident,
|
||||
pub id: NodeId,
|
||||
pub bounds: TyParamBounds,
|
||||
pub unbound: Option<TraitRef>,
|
||||
pub default: Option<P<Ty>>,
|
||||
pub span: Span
|
||||
}
|
||||
|
@ -1489,7 +1496,7 @@ pub struct PolyTraitRef {
|
|||
pub bound_lifetimes: Vec<LifetimeDef>,
|
||||
|
||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
|
||||
pub trait_ref: TraitRef
|
||||
pub trait_ref: TraitRef,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
|
||||
|
@ -1578,8 +1585,6 @@ pub enum Item_ {
|
|||
/// Represents a Trait Declaration
|
||||
ItemTrait(Unsafety,
|
||||
Generics,
|
||||
Option<TraitRef>, // (optional) default bound not required for Self.
|
||||
// Currently, only Sized makes sense here.
|
||||
TyParamBounds,
|
||||
Vec<TraitItem>),
|
||||
ItemImpl(Unsafety,
|
||||
|
|
|
@ -780,9 +780,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
|||
None => {}
|
||||
}
|
||||
}
|
||||
ItemTrait(_, _, _, ref bounds, ref trait_items) => {
|
||||
ItemTrait(_, _, ref bounds, ref trait_items) => {
|
||||
for b in bounds.iter() {
|
||||
if let TraitTyParamBound(ref t) = *b {
|
||||
if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b {
|
||||
self.insert(t.trait_ref.ref_id, NodeItem(i));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,11 +139,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
|
|||
.collect();
|
||||
ast::ItemImpl(u, a, b, c, impl_items)
|
||||
}
|
||||
ast::ItemTrait(u, a, b, c, methods) => {
|
||||
ast::ItemTrait(u, a, b, methods) => {
|
||||
let methods = methods.into_iter()
|
||||
.filter(|m| trait_method_in_cfg(cx, m))
|
||||
.collect();
|
||||
ast::ItemTrait(u, a, b, c, methods)
|
||||
ast::ItemTrait(u, a, b, methods)
|
||||
}
|
||||
ast::ItemStruct(def, generics) => {
|
||||
ast::ItemStruct(fold_struct(cx, def), generics)
|
||||
|
|
|
@ -68,7 +68,6 @@ pub trait AstBuilder {
|
|||
span: Span,
|
||||
id: ast::Ident,
|
||||
bounds: OwnedSlice<ast::TyParamBound>,
|
||||
unbound: Option<ast::TraitRef>,
|
||||
default: Option<P<ast::Ty>>) -> ast::TyParam;
|
||||
|
||||
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
|
||||
|
@ -414,13 +413,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
span: Span,
|
||||
id: ast::Ident,
|
||||
bounds: OwnedSlice<ast::TyParamBound>,
|
||||
unbound: Option<ast::TraitRef>,
|
||||
default: Option<P<ast::Ty>>) -> ast::TyParam {
|
||||
ast::TyParam {
|
||||
ident: id,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
bounds: bounds,
|
||||
unbound: unbound,
|
||||
default: default,
|
||||
span: span
|
||||
}
|
||||
|
@ -455,7 +452,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
}
|
||||
|
||||
fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
|
||||
ast::TraitTyParamBound(self.poly_trait_ref(path))
|
||||
ast::TraitTyParamBound(self.poly_trait_ref(path), ast::TraitBoundModifier::None)
|
||||
}
|
||||
|
||||
fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
|
||||
|
|
|
@ -58,10 +58,10 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
|
|||
additional_bounds: Vec::new(),
|
||||
generics: LifetimeBounds {
|
||||
lifetimes: Vec::new(),
|
||||
bounds: vec!(("__D", None, vec!(Path::new_(
|
||||
bounds: vec!(("__D", vec!(Path::new_(
|
||||
vec!(krate, "Decoder"), None,
|
||||
vec!(box Literal(Path::new_local("__E"))), true))),
|
||||
("__E", None, vec!()))
|
||||
("__E", vec!()))
|
||||
},
|
||||
methods: vec!(
|
||||
MethodDef {
|
||||
|
|
|
@ -134,10 +134,10 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
|
|||
additional_bounds: Vec::new(),
|
||||
generics: LifetimeBounds {
|
||||
lifetimes: Vec::new(),
|
||||
bounds: vec!(("__S", None, vec!(Path::new_(
|
||||
bounds: vec!(("__S", vec!(Path::new_(
|
||||
vec!(krate, "Encoder"), None,
|
||||
vec!(box Literal(Path::new_local("__E"))), true))),
|
||||
("__E", None, vec!()))
|
||||
("__E", vec!()))
|
||||
},
|
||||
methods: vec!(
|
||||
MethodDef {
|
||||
|
|
|
@ -417,7 +417,6 @@ impl<'a> TraitDef<'a> {
|
|||
cx.typaram(self.span,
|
||||
ty_param.ident,
|
||||
OwnedSlice::from_vec(bounds),
|
||||
ty_param.unbound.clone(),
|
||||
None)
|
||||
}));
|
||||
|
||||
|
|
|
@ -189,15 +189,19 @@ impl<'a> Ty<'a> {
|
|||
}
|
||||
|
||||
|
||||
fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
|
||||
bounds: &[Path], unbound: Option<ast::TraitRef>,
|
||||
self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
|
||||
fn mk_ty_param(cx: &ExtCtxt,
|
||||
span: Span,
|
||||
name: &str,
|
||||
bounds: &[Path],
|
||||
self_ident: Ident,
|
||||
self_generics: &Generics)
|
||||
-> ast::TyParam {
|
||||
let bounds =
|
||||
bounds.iter().map(|b| {
|
||||
let path = b.to_path(cx, span, self_ident, self_generics);
|
||||
cx.typarambound(path)
|
||||
}).collect();
|
||||
cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
|
||||
cx.typaram(span, cx.ident_of(name), bounds, None)
|
||||
}
|
||||
|
||||
fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>)
|
||||
|
@ -216,7 +220,7 @@ fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>)
|
|||
#[deriving(Clone)]
|
||||
pub struct LifetimeBounds<'a> {
|
||||
pub lifetimes: Vec<(&'a str, Vec<&'a str>)>,
|
||||
pub bounds: Vec<(&'a str, Option<ast::TraitRef>, Vec<Path<'a>>)>,
|
||||
pub bounds: Vec<(&'a str, Vec<Path<'a>>)>,
|
||||
}
|
||||
|
||||
impl<'a> LifetimeBounds<'a> {
|
||||
|
@ -239,12 +243,11 @@ impl<'a> LifetimeBounds<'a> {
|
|||
}).collect();
|
||||
let ty_params = self.bounds.iter().map(|t| {
|
||||
match t {
|
||||
&(ref name, ref unbound, ref bounds) => {
|
||||
&(ref name, ref bounds) => {
|
||||
mk_ty_param(cx,
|
||||
span,
|
||||
*name,
|
||||
bounds.as_slice(),
|
||||
unbound.clone(),
|
||||
self_ty,
|
||||
self_generics)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
|
|||
vec!(box Literal(Path::new_local("__S"))), true),
|
||||
LifetimeBounds {
|
||||
lifetimes: Vec::new(),
|
||||
bounds: vec!(("__S", None,
|
||||
bounds: vec!(("__S",
|
||||
vec!(Path::new(vec!("std", "hash", "Writer"))))),
|
||||
},
|
||||
Path::new_local("__S"))
|
||||
|
|
|
@ -36,7 +36,6 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
|
|||
generics: LifetimeBounds {
|
||||
lifetimes: Vec::new(),
|
||||
bounds: vec!(("R",
|
||||
None,
|
||||
vec!( Path::new(vec!("std", "rand", "Rng")) )))
|
||||
},
|
||||
explicit_self: None,
|
||||
|
|
|
@ -736,18 +736,17 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
|
|||
-> TyParamBound
|
||||
where T: Folder {
|
||||
match tpb {
|
||||
TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_poly_trait_ref(ty)),
|
||||
TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier),
|
||||
RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
|
||||
let TyParam {id, ident, bounds, unbound, default, span} = tp;
|
||||
let TyParam {id, ident, bounds, default, span} = tp;
|
||||
TyParam {
|
||||
id: fld.new_id(id),
|
||||
ident: ident,
|
||||
bounds: fld.fold_bounds(bounds),
|
||||
unbound: unbound.map(|x| fld.fold_trait_ref(x)),
|
||||
default: default.map(|x| fld.fold_ty(x)),
|
||||
span: span
|
||||
}
|
||||
|
@ -1043,7 +1042,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
|||
folder.fold_ty(ty),
|
||||
new_impl_items)
|
||||
}
|
||||
ItemTrait(unsafety, generics, unbound, bounds, methods) => {
|
||||
ItemTrait(unsafety, generics, bounds, methods) => {
|
||||
let bounds = folder.fold_bounds(bounds);
|
||||
let methods = methods.into_iter().flat_map(|method| {
|
||||
let r = match method {
|
||||
|
@ -1073,7 +1072,6 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
|||
}).collect();
|
||||
ItemTrait(unsafety,
|
||||
folder.fold_generics(generics),
|
||||
unbound,
|
||||
bounds,
|
||||
methods)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use self::ItemOrViewItem::*;
|
|||
|
||||
use abi;
|
||||
use ast::{AssociatedType, BareFnTy, ClosureTy};
|
||||
use ast::{RegionTyParamBound, TraitTyParamBound};
|
||||
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{ProvidedMethod, Public, Unsafety};
|
||||
use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
|
||||
use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, Block};
|
||||
|
@ -117,6 +117,13 @@ pub enum PathParsingMode {
|
|||
LifetimeAndTypesWithColons,
|
||||
}
|
||||
|
||||
/// How to parse a bound, whether to allow bound modifiers such as `?`.
|
||||
#[deriving(Copy, PartialEq)]
|
||||
pub enum BoundParsingMode {
|
||||
Bare,
|
||||
Modified,
|
||||
}
|
||||
|
||||
enum ItemOrViewItem {
|
||||
/// Indicates a failure to parse any kind of item. The attributes are
|
||||
/// returned.
|
||||
|
@ -1087,12 +1094,12 @@ impl<'a> Parser<'a> {
|
|||
let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs,
|
||||
trait_ref: trait_ref };
|
||||
let other_bounds = if self.eat(&token::BinOp(token::Plus)) {
|
||||
self.parse_ty_param_bounds()
|
||||
self.parse_ty_param_bounds(BoundParsingMode::Bare)
|
||||
} else {
|
||||
OwnedSlice::empty()
|
||||
};
|
||||
let all_bounds =
|
||||
Some(TraitTyParamBound(poly_trait_ref)).into_iter()
|
||||
Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter()
|
||||
.chain(other_bounds.into_vec().into_iter())
|
||||
.collect();
|
||||
ast::TyPolyTraitRef(all_bounds)
|
||||
|
@ -1165,7 +1172,7 @@ impl<'a> Parser<'a> {
|
|||
// To be helpful, parse the proc as ever
|
||||
let _ = self.parse_legacy_lifetime_defs(lifetime_defs);
|
||||
let _ = self.parse_fn_args(false, false);
|
||||
let _ = self.parse_colon_then_ty_param_bounds();
|
||||
let _ = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
|
||||
let _ = self.parse_ret_ty();
|
||||
|
||||
self.obsolete(proc_span, ObsoleteProcType);
|
||||
|
@ -1255,7 +1262,7 @@ impl<'a> Parser<'a> {
|
|||
inputs
|
||||
};
|
||||
|
||||
let bounds = self.parse_colon_then_ty_param_bounds();
|
||||
let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
|
||||
|
||||
let output = self.parse_ret_ty();
|
||||
let decl = P(FnDecl {
|
||||
|
@ -1481,7 +1488,7 @@ impl<'a> Parser<'a> {
|
|||
return lhs;
|
||||
}
|
||||
|
||||
let bounds = self.parse_ty_param_bounds();
|
||||
let bounds = self.parse_ty_param_bounds(BoundParsingMode::Bare);
|
||||
|
||||
// In type grammar, `+` is treated like a binary operator,
|
||||
// and hence both L and R side are required.
|
||||
|
@ -4022,13 +4029,14 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// Parses a sequence of bounds if a `:` is found,
|
||||
// otherwise returns empty list.
|
||||
fn parse_colon_then_ty_param_bounds(&mut self)
|
||||
fn parse_colon_then_ty_param_bounds(&mut self,
|
||||
mode: BoundParsingMode)
|
||||
-> OwnedSlice<TyParamBound>
|
||||
{
|
||||
if !self.eat(&token::Colon) {
|
||||
OwnedSlice::empty()
|
||||
} else {
|
||||
self.parse_ty_param_bounds()
|
||||
self.parse_ty_param_bounds(mode)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4036,14 +4044,20 @@ impl<'a> Parser<'a> {
|
|||
// where boundseq = ( polybound + boundseq ) | polybound
|
||||
// and polybound = ( 'for' '<' 'region '>' )? bound
|
||||
// and bound = 'region | trait_ref
|
||||
// NB: The None/Some distinction is important for issue #7264.
|
||||
fn parse_ty_param_bounds(&mut self)
|
||||
fn parse_ty_param_bounds(&mut self,
|
||||
mode: BoundParsingMode)
|
||||
-> OwnedSlice<TyParamBound>
|
||||
{
|
||||
let mut result = vec!();
|
||||
loop {
|
||||
let question_span = self.span;
|
||||
let ate_question = self.eat(&token::Question);
|
||||
match self.token {
|
||||
token::Lifetime(lifetime) => {
|
||||
if ate_question {
|
||||
self.span_err(question_span,
|
||||
"`?` may only modify trait bounds, not lifetime bounds");
|
||||
}
|
||||
result.push(RegionTyParamBound(ast::Lifetime {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
|
@ -4053,7 +4067,18 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
token::ModSep | token::Ident(..) => {
|
||||
let poly_trait_ref = self.parse_poly_trait_ref();
|
||||
result.push(TraitTyParamBound(poly_trait_ref))
|
||||
let modifier = if ate_question {
|
||||
if mode == BoundParsingMode::Modified {
|
||||
TraitBoundModifier::Maybe
|
||||
} else {
|
||||
self.span_err(question_span,
|
||||
"unexpected `?`");
|
||||
TraitBoundModifier::None
|
||||
}
|
||||
} else {
|
||||
TraitBoundModifier::None
|
||||
};
|
||||
result.push(TraitTyParamBound(poly_trait_ref, modifier))
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
@ -4082,13 +4107,14 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
|
||||
/// Matches typaram = (unbound `?`)? IDENT (`?` unbound)? optbounds ( EQ ty )?
|
||||
fn parse_ty_param(&mut self) -> TyParam {
|
||||
// This is a bit hacky. Currently we are only interested in a single
|
||||
// unbound, and it may only be `Sized`. To avoid backtracking and other
|
||||
// complications, we parse an ident, then check for `?`. If we find it,
|
||||
// we use the ident as the unbound, otherwise, we use it as the name of
|
||||
// type param.
|
||||
// type param. Even worse, for now, we need to check for `?` before or
|
||||
// after the bound.
|
||||
let mut span = self.span;
|
||||
let mut ident = self.parse_ident();
|
||||
let mut unbound = None;
|
||||
|
@ -4099,7 +4125,14 @@ impl<'a> Parser<'a> {
|
|||
ident = self.parse_ident();
|
||||
}
|
||||
|
||||
let bounds = self.parse_colon_then_ty_param_bounds();
|
||||
let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Modified);
|
||||
if let Some(unbound) = unbound {
|
||||
let mut bounds_as_vec = bounds.into_vec();
|
||||
bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![],
|
||||
trait_ref: unbound },
|
||||
TraitBoundModifier::Maybe));
|
||||
bounds = OwnedSlice::from_vec(bounds_as_vec);
|
||||
};
|
||||
|
||||
let default = if self.check(&token::Eq) {
|
||||
self.bump();
|
||||
|
@ -4111,7 +4144,6 @@ impl<'a> Parser<'a> {
|
|||
ident: ident,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
bounds: bounds,
|
||||
unbound: unbound,
|
||||
default: default,
|
||||
span: span,
|
||||
}
|
||||
|
@ -4253,7 +4285,7 @@ impl<'a> Parser<'a> {
|
|||
let bounded_ty = self.parse_ty();
|
||||
|
||||
if self.eat(&token::Colon) {
|
||||
let bounds = self.parse_ty_param_bounds();
|
||||
let bounds = self.parse_ty_param_bounds(BoundParsingMode::Bare);
|
||||
let hi = self.span.hi;
|
||||
let span = mk_sp(lo, hi);
|
||||
|
||||
|
@ -4740,15 +4772,23 @@ impl<'a> Parser<'a> {
|
|||
fn parse_item_trait(&mut self, unsafety: Unsafety) -> ItemInfo {
|
||||
let ident = self.parse_ident();
|
||||
let mut tps = self.parse_generics();
|
||||
let sized = self.parse_for_sized();
|
||||
let unbound = self.parse_for_sized();
|
||||
|
||||
// Parse supertrait bounds.
|
||||
let bounds = self.parse_colon_then_ty_param_bounds();
|
||||
let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
|
||||
|
||||
if let Some(unbound) = unbound {
|
||||
let mut bounds_as_vec = bounds.into_vec();
|
||||
bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![],
|
||||
trait_ref: unbound },
|
||||
TraitBoundModifier::Maybe));
|
||||
bounds = OwnedSlice::from_vec(bounds_as_vec);
|
||||
};
|
||||
|
||||
self.parse_where_clause(&mut tps);
|
||||
|
||||
let meths = self.parse_trait_items();
|
||||
(ident, ItemTrait(unsafety, tps, sized, bounds, meths), None)
|
||||
(ident, ItemTrait(unsafety, tps, bounds, meths), None)
|
||||
}
|
||||
|
||||
fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
|
||||
|
@ -4967,12 +5007,25 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn parse_for_sized(&mut self) -> Option<ast::TraitRef> {
|
||||
// FIXME, this should really use TraitBoundModifier, but it will get
|
||||
// re-jigged shortly in any case, so leaving the hacky version for now.
|
||||
if self.eat_keyword(keywords::For) {
|
||||
let span = self.span;
|
||||
let mut ate_question = false;
|
||||
if self.eat(&token::Question) {
|
||||
ate_question = true;
|
||||
}
|
||||
let ident = self.parse_ident();
|
||||
if !self.eat(&token::Question) {
|
||||
if self.eat(&token::Question) {
|
||||
if ate_question {
|
||||
self.span_err(span,
|
||||
"unexpected `?`");
|
||||
}
|
||||
ate_question = true;
|
||||
}
|
||||
if !ate_question {
|
||||
self.span_err(span,
|
||||
"expected 'Sized?' after `for` in trait item");
|
||||
"expected `?Sized` after `for` in trait item");
|
||||
return None;
|
||||
}
|
||||
let tref = Parser::trait_ref_from_ident(ident, span);
|
||||
|
|
|
@ -13,7 +13,7 @@ pub use self::AnnNode::*;
|
|||
use abi;
|
||||
use ast::{mod, FnUnboxedClosureKind, FnMutUnboxedClosureKind};
|
||||
use ast::{FnOnceUnboxedClosureKind};
|
||||
use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound};
|
||||
use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem};
|
||||
use ast::{UnboxedClosureKind};
|
||||
use ast_util;
|
||||
|
@ -958,19 +958,19 @@ impl<'a> State<'a> {
|
|||
}
|
||||
try!(self.bclose(item.span));
|
||||
}
|
||||
ast::ItemTrait(unsafety, ref generics, ref unbound, ref bounds, ref methods) => {
|
||||
ast::ItemTrait(unsafety, ref generics, ref bounds, ref methods) => {
|
||||
try!(self.head(""));
|
||||
try!(self.print_visibility(item.vis));
|
||||
try!(self.print_unsafety(unsafety));
|
||||
try!(self.word_nbsp("trait"));
|
||||
try!(self.print_ident(item.ident));
|
||||
try!(self.print_generics(generics));
|
||||
if let &Some(ref tref) = unbound {
|
||||
// TODO find and print the unbound, remove it from bounds
|
||||
/*if let &Some(ref tref) = unbound {
|
||||
try!(space(&mut self.s));
|
||||
try!(self.word_space("for"));
|
||||
try!(self.word_space("for ?"));
|
||||
try!(self.print_trait_ref(tref));
|
||||
try!(word(&mut self.s, "?"));
|
||||
}
|
||||
}*/
|
||||
try!(self.print_bounds(":", bounds[]));
|
||||
try!(self.print_where_clause(generics));
|
||||
try!(word(&mut self.s, " "));
|
||||
|
@ -2361,7 +2361,11 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
try!(match *bound {
|
||||
TraitTyParamBound(ref tref) => {
|
||||
TraitTyParamBound(ref tref, TraitBoundModifier::None) => {
|
||||
self.print_poly_trait_ref(tref)
|
||||
}
|
||||
TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => {
|
||||
try!(word(&mut self.s, "?"));
|
||||
self.print_poly_trait_ref(tref)
|
||||
}
|
||||
RegionTyParamBound(ref lt) => {
|
||||
|
@ -2428,10 +2432,6 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
|
||||
if let Some(ref tref) = param.unbound {
|
||||
try!(self.print_trait_ref(tref));
|
||||
try!(self.word_space("?"));
|
||||
}
|
||||
try!(self.print_ident(param.ident));
|
||||
try!(self.print_bounds(":", param.bounds[]));
|
||||
match param.default {
|
||||
|
|
|
@ -85,8 +85,8 @@ pub trait Visitor<'v> {
|
|||
fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
|
||||
walk_ty_param_bound(self, bounds)
|
||||
}
|
||||
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef) {
|
||||
walk_poly_trait_ref(self, t)
|
||||
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
|
||||
walk_poly_trait_ref(self, t, m)
|
||||
}
|
||||
fn visit_struct_def(&mut self, s: &'v StructDef, _: Ident, _: &'v Generics, _: NodeId) {
|
||||
walk_struct_def(self, s)
|
||||
|
@ -244,7 +244,8 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
|
|||
/// Like with walk_method_helper this doesn't correspond to a method
|
||||
/// in Visitor, and so it gets a _helper suffix.
|
||||
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
||||
trait_ref: &'v PolyTraitRef)
|
||||
trait_ref: &'v PolyTraitRef,
|
||||
_modifier: &'v TraitBoundModifier)
|
||||
where V: Visitor<'v>
|
||||
{
|
||||
walk_lifetime_decls_helper(visitor, &trait_ref.bound_lifetimes);
|
||||
|
@ -324,7 +325,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
|||
generics,
|
||||
item.id)
|
||||
}
|
||||
ItemTrait(_, ref generics, _, ref bounds, ref methods) => {
|
||||
ItemTrait(_, ref generics, ref bounds, ref methods) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_ty_param_bounds_helper(visitor, bounds);
|
||||
for method in methods.iter() {
|
||||
|
@ -558,8 +559,8 @@ pub fn walk_ty_param_bounds_helper<'v, V: Visitor<'v>>(visitor: &mut V,
|
|||
pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
bound: &'v TyParamBound) {
|
||||
match *bound {
|
||||
TraitTyParamBound(ref typ) => {
|
||||
visitor.visit_poly_trait_ref(typ);
|
||||
TraitTyParamBound(ref typ, ref modifier) => {
|
||||
visitor.visit_poly_trait_ref(typ, modifier);
|
||||
}
|
||||
RegionTyParamBound(ref lifetime) => {
|
||||
visitor.visit_lifetime_bound(lifetime);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue