ty::mk_closure(tcx, fn_decl)
}
- ast::TyPolyTraitRef(ref data) => {
- // FIXME(#18639) this is just a placeholder for code to come
- let principal = instantiate_trait_ref(this, rscope, &data.trait_ref, None, None);
- let bounds = conv_existential_bounds(this,
- rscope,
- ast_ty.span,
- &[principal.clone()],
- &[]);
- ty::mk_trait(tcx, (*principal).clone(), bounds)
+ ast::TyPolyTraitRef(ref bounds) => {
+ conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds.as_slice())
}
ast::TyPath(ref path, ref bounds, id) => {
let a_def = match tcx.def_map.borrow().get(&id) {
let ast_bound_refs: Vec<&ast::TyParamBound> =
ast_bounds.iter().collect();
+ let partitioned_bounds =
+ partition_bounds(this.tcx(), span, ast_bound_refs.as_slice());
+
+ conv_existential_bounds_from_partitioned_bounds(
+ this, rscope, span, main_trait_refs, partitioned_bounds)
+}
+
+fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
+ this: &AC,
+ rscope: &RS,
+ span: Span,
+ ast_bounds: &[ast::TyParamBound])
+ -> ty::t
+ where AC: AstConv<'tcx>, RS:RegionScope
+{
+ let ast_bounds: Vec<&ast::TyParamBound> = ast_bounds.iter().collect();
+ let mut partitioned_bounds = partition_bounds(this.tcx(), span, ast_bounds[]);
+
+ let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
+ Some(trait_bound) => {
+ Some(instantiate_poly_trait_ref(this, rscope, trait_bound, None, None))
+ }
+ None => {
+ this.tcx().sess.span_err(
+ span,
+ "at least one non-builtin trait is required for an object type");
+ None
+ }
+ };
+
+ let bounds = conv_existential_bounds_from_partitioned_bounds(this,
+ rscope,
+ span,
+ main_trait_bound.as_slice(),
+ partitioned_bounds);
+
+ match main_trait_bound {
+ None => ty::mk_err(),
+ Some(principal) => ty::mk_trait(this.tcx(), (*principal).clone(), bounds)
+ }
+}
+
+pub fn conv_existential_bounds_from_partitioned_bounds<'tcx, AC, RS>(
+ this: &AC,
+ rscope: &RS,
+ span: Span,
+ main_trait_refs: &[Rc<ty::TraitRef>],
+ partitioned_bounds: PartitionedBounds)
+ -> ty::ExistentialBounds
+ where AC: AstConv<'tcx>, RS:RegionScope
+{
let PartitionedBounds { builtin_bounds,
trait_bounds,
region_bounds } =
- partition_bounds(this.tcx(), span, ast_bound_refs.as_slice());
+ partitioned_bounds;
if !trait_bounds.is_empty() {
let b = &trait_bounds[0];
this.tcx().sess.span_err(
- b.path.span,
+ b.trait_ref.path.span,
format!("only the builtin traits can be used \
as closure or object bounds").as_slice());
}
fn visit_ty_method(&mut self, t: &'v TypeMethod) { walk_ty_method(self, t) }
fn visit_trait_item(&mut self, t: &'v TraitItem) { walk_trait_item(self, t) }
fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
+ 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_path(&mut self, path: &'v Path, _id: ast::NodeId) {
walk_path(self, path)
}
+ fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
+ walk_path_segment(self, path_span, path_segment)
+ }
+ fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
+ walk_path_parameters(self, path_span, path_parameters)
+ }
fn visit_attribute(&mut self, _attr: &'v Attribute) {}
}
ViewPathGlob(ref path, id) => {
visitor.visit_path(path, id);
}
- ViewPathList(ref path, ref list, _) => {
+ ViewPathList(ref prefix, ref list, _) => {
for id in list.iter() {
match id.node {
PathListIdent { name, .. } => {
PathListMod { .. } => ()
}
}
- walk_path(visitor, path);
+
+ // Note that the `prefix` here is not a complete
+ // path, so we don't use `visit_path`.
+ walk_path(visitor, prefix);
}
}
}
trait_ref: &'v PolyTraitRef)
where V: Visitor<'v>
{
- walk_lifetime_decls(visitor, &trait_ref.bound_lifetimes);
+ walk_lifetime_decls_helper(visitor, &trait_ref.bound_lifetimes);
visitor.visit_trait_ref(&trait_ref.trait_ref);
}
}
ItemTrait(ref generics, _, ref bounds, ref methods) => {
visitor.visit_generics(generics);
- walk_ty_param_bounds(visitor, bounds);
+ walk_ty_param_bounds_helper(visitor, bounds);
for method in methods.iter() {
visitor.visit_trait_item(method)
}
visitor.visit_ty(&*argument.ty)
}
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
- walk_ty_param_bounds(visitor, &function_declaration.bounds);
- walk_lifetime_decls(visitor, &function_declaration.lifetimes);
+ walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
+ walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
}
TyProc(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(&*argument.ty)
}
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
- walk_ty_param_bounds(visitor, &function_declaration.bounds);
- walk_lifetime_decls(visitor, &function_declaration.lifetimes);
+ walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
+ walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
}
TyBareFn(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(&*argument.ty)
}
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
- walk_lifetime_decls(visitor, &function_declaration.lifetimes);
+ walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
}
TyPath(ref path, ref opt_bounds, id) => {
visitor.visit_path(path, id);
match *opt_bounds {
Some(ref bounds) => {
- walk_ty_param_bounds(visitor, bounds);
+ walk_ty_param_bounds_helper(visitor, bounds);
}
None => { }
}
visitor.visit_ty(&**ty);
visitor.visit_expr(&**expression)
}
- TyPolyTraitRef(ref poly_trait_ref) => {
- visitor.visit_poly_trait_ref(&**poly_trait_ref)
+ TyPolyTraitRef(ref bounds) => {
+ walk_ty_param_bounds_helper(visitor, bounds)
}
TyTypeof(ref expression) => {
visitor.visit_expr(&**expression)
}
}
-fn walk_lifetime_decls<'v, V: Visitor<'v>>(visitor: &mut V,
- lifetimes: &'v Vec<LifetimeDef>) {
+pub fn walk_lifetime_decls_helper<'v, V: Visitor<'v>>(visitor: &mut V,
+ lifetimes: &'v Vec<LifetimeDef>) {
for l in lifetimes.iter() {
visitor.visit_lifetime_decl(l);
}
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
for segment in path.segments.iter() {
- visitor.visit_ident(path.span, segment.identifier);
+ visitor.visit_path_segment(path.span, segment);
+ }
+}
- match segment.parameters {
- ast::AngleBracketedParameters(ref data) => {
- for typ in data.types.iter() {
- visitor.visit_ty(&**typ);
- }
- for lifetime in data.lifetimes.iter() {
- visitor.visit_lifetime_ref(lifetime);
- }
+pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
+ path_span: Span,
+ segment: &'v PathSegment) {
+ visitor.visit_ident(path_span, segment.identifier);
+ visitor.visit_path_parameters(path_span, &segment.parameters);
+}
+
+pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
+ _path_span: Span,
+ path_parameters: &'v PathParameters) {
+ match *path_parameters {
+ ast::AngleBracketedParameters(ref data) => {
+ for typ in data.types.iter() {
+ visitor.visit_ty(&**typ);
}
- ast::ParenthesizedParameters(ref data) => {
- for typ in data.inputs.iter() {
- visitor.visit_ty(&**typ);
- }
- for typ in data.output.iter() {
- visitor.visit_ty(&**typ);
- }
+ for lifetime in data.lifetimes.iter() {
+ visitor.visit_lifetime_ref(lifetime);
+ }
+ }
+ ast::ParenthesizedParameters(ref data) => {
+ for typ in data.inputs.iter() {
+ visitor.visit_ty(&**typ);
+ }
+ for typ in data.output.iter() {
+ visitor.visit_ty(&**typ);
}
}
}
}
}
-pub fn walk_ty_param_bounds<'v, V: Visitor<'v>>(visitor: &mut V,
- bounds: &'v OwnedSlice<TyParamBound>) {
+pub fn walk_ty_param_bounds_helper<'v, V: Visitor<'v>>(visitor: &mut V,
+ bounds: &'v OwnedSlice<TyParamBound>) {
for bound in bounds.iter() {
- match *bound {
- TraitTyParamBound(ref typ) => {
- visitor.visit_poly_trait_ref(typ)
- }
- RegionTyParamBound(ref lifetime) => {
- visitor.visit_lifetime_ref(lifetime);
- }
+ visitor.visit_ty_param_bound(bound)
+ }
+}
+
+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);
+ }
+ RegionTyParamBound(ref lifetime) => {
+ visitor.visit_lifetime_ref(lifetime);
}
}
}
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
for type_parameter in generics.ty_params.iter() {
- walk_ty_param_bounds(visitor, &type_parameter.bounds);
+ walk_ty_param_bounds_helper(visitor, &type_parameter.bounds);
match type_parameter.default {
Some(ref ty) => visitor.visit_ty(&**ty),
None => {}
}
}
- walk_lifetime_decls(visitor, &generics.lifetimes);
+ walk_lifetime_decls_helper(visitor, &generics.lifetimes);
for predicate in generics.where_clause.predicates.iter() {
visitor.visit_ident(predicate.span, predicate.ident);
- walk_ty_param_bounds(visitor, &predicate.bounds);
+ walk_ty_param_bounds_helper(visitor, &predicate.bounds);
}
}