use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::wf::object_region_bounds;
-use rustc::lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES;
use rustc_back::slice;
use require_c_abi_if_variadic;
-use util::common::{ErrorReported, FN_OUTPUT_NAME};
+use util::common::ErrorReported;
use util::nodemap::FxHashSet;
use std::iter;
use syntax::{abi, ast};
use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax::symbol::Symbol;
use syntax_pos::Span;
pub trait AstConv<'gcx, 'tcx> {
item_segment: &hir::PathSegment)
-> &'tcx Substs<'tcx>
{
- let tcx = self.tcx();
-
- match item_segment.parameters {
- hir::AngleBracketedParameters(_) => {}
- hir::ParenthesizedParameters(..) => {
- self.prohibit_parenthesized_params(item_segment, true);
-
- return Substs::for_item(tcx, def_id, |_, _| {
- tcx.types.re_static
- }, |_, _| {
- tcx.types.err
- });
- }
- }
-
let (substs, assoc_bindings) =
self.create_substs_for_ast_path(span,
def_id,
parameters={:?})",
def_id, self_ty, parameters);
- let (lifetimes, num_types_provided, infer_types) = match *parameters {
- hir::AngleBracketedParameters(ref data) => {
- (&data.lifetimes[..], data.types.len(), data.infer_types)
- }
- hir::ParenthesizedParameters(_) => (&[][..], 1, false)
- };
-
// If the type is parameterized by this region, then replace this
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
let decl_generics = tcx.generics_of(def_id);
+ let num_types_provided = parameters.types.len();
let expected_num_region_params = decl_generics.regions.len();
- let supplied_num_region_params = lifetimes.len();
+ let supplied_num_region_params = parameters.lifetimes.len();
if expected_num_region_params != supplied_num_region_params {
report_lifetime_number_error(tcx, span,
supplied_num_region_params,
// Check the number of type parameters supplied by the user.
let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
- if !infer_types || num_types_provided > ty_param_defs.len() {
+ if !parameters.infer_types || num_types_provided > ty_param_defs.len() {
check_type_argument_count(tcx, span, num_types_provided, ty_param_defs);
}
false
};
- let mut output_assoc_binding = None;
let substs = Substs::for_item(tcx, def_id, |def, _| {
let i = def.index as usize - self_ty.is_some() as usize;
- if let Some(lifetime) = lifetimes.get(i) {
+ if let Some(lifetime) = parameters.lifetimes.get(i) {
self.ast_region_to_region(lifetime, Some(def))
} else {
tcx.types.re_static
let i = i - self_ty.is_some() as usize - decl_generics.regions.len();
if i < num_types_provided {
// A provided type parameter.
- match *parameters {
- hir::AngleBracketedParameters(ref data) => {
- self.ast_ty_to_ty(&data.types[i])
- }
- hir::ParenthesizedParameters(ref data) => {
- assert_eq!(i, 0);
- let (ty, assoc) = self.convert_parenthesized_parameters(data);
- output_assoc_binding = Some(assoc);
- ty
- }
- }
- } else if infer_types {
+ self.ast_ty_to_ty(¶meters.types[i])
+ } else if parameters.infer_types {
// No type parameters were provided, we can infer all.
let ty_var = if !default_needs_object_self(def) {
self.ty_infer_for_def(def, substs, span)
}
});
- let assoc_bindings = match *parameters {
- hir::AngleBracketedParameters(ref data) => {
- data.bindings.iter().map(|b| {
- ConvertedBinding {
- item_name: b.name,
- ty: self.ast_ty_to_ty(&b.ty),
- span: b.span
- }
- }).collect()
- }
- hir::ParenthesizedParameters(ref data) => {
- vec![output_assoc_binding.unwrap_or_else(|| {
- // This is an error condition, but we should
- // get the associated type binding anyway.
- self.convert_parenthesized_parameters(data).1
- })]
+ let assoc_bindings = parameters.bindings.iter().map(|binding| {
+ ConvertedBinding {
+ item_name: binding.name,
+ ty: self.ast_ty_to_ty(&binding.ty),
+ span: binding.span,
}
- };
+ }).collect();
debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
decl_generics, self_ty, substs);
(substs, assoc_bindings)
}
- fn convert_parenthesized_parameters(&self,
- data: &hir::ParenthesizedParameterData)
- -> (Ty<'tcx>, ConvertedBinding<'tcx>)
- {
- let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| {
- self.ast_ty_to_ty(a_t)
- }));
-
- let (output, output_span) = match data.output {
- Some(ref output_ty) => {
- (self.ast_ty_to_ty(output_ty), output_ty.span)
- }
- None => {
- (self.tcx().mk_nil(), data.span)
- }
- };
-
- let output_binding = ConvertedBinding {
- item_name: Symbol::intern(FN_OUTPUT_NAME),
- ty: output,
- span: output_span
- };
-
- (self.tcx().mk_ty(ty::TyTuple(inputs, false)), output_binding)
- }
-
/// Instantiates the path for the given trait reference, assuming that it's
/// bound to a valid trait type. Returns the def_id for the defining trait.
/// Fails if the type is a type other than a trait type.
let trait_def = self.tcx().trait_def(trait_def_id);
- match trait_segment.parameters {
- hir::AngleBracketedParameters(_) => {
- // For now, require that parenthetical notation be used
- // only with `Fn()` etc.
- if !self.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
- emit_feature_err(&self.tcx().sess.parse_sess,
- "unboxed_closures", span, GateIssue::Language,
- "\
- the precise format of `Fn`-family traits' \
- type parameters is subject to change. \
- Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
- }
- }
- hir::ParenthesizedParameters(_) => {
- // For now, require that parenthetical notation be used
- // only with `Fn()` etc.
- if !self.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
- emit_feature_err(&self.tcx().sess.parse_sess,
- "unboxed_closures", span, GateIssue::Language,
- "\
- parenthetical notation is only stable when used with `Fn`-family traits");
- }
- }
+ if !self.tcx().sess.features.borrow().unboxed_closures &&
+ trait_segment.parameters.parenthesized != trait_def.paren_sugar {
+ // For now, require that parenthetical notation be used only with `Fn()` etc.
+ let msg = if trait_def.paren_sugar {
+ "the precise format of `Fn`-family traits' type parameters is subject to change. \
+ Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead"
+ } else {
+ "parenthetical notation is only stable when used with `Fn`-family traits"
+ };
+ emit_feature_err(&self.tcx().sess.parse_sess, "unboxed_closures",
+ span, GateIssue::Language, msg);
}
self.create_substs_for_ast_path(span,
pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
for segment in segments {
- if let hir::ParenthesizedParameters(_) = segment.parameters {
- self.prohibit_parenthesized_params(segment, false);
- break;
- }
- for typ in segment.parameters.types() {
+ for typ in &segment.parameters.types {
struct_span_err!(self.tcx().sess, typ.span, E0109,
"type parameters are not allowed on this type")
.span_label(typ.span, "type parameter not allowed")
.emit();
break;
}
- for lifetime in segment.parameters.lifetimes() {
+ for lifetime in &segment.parameters.lifetimes {
struct_span_err!(self.tcx().sess, lifetime.span, E0110,
"lifetime parameters are not allowed on this type")
.span_label(lifetime.span,
.emit();
break;
}
- for binding in segment.parameters.bindings() {
+ for binding in &segment.parameters.bindings {
self.prohibit_projection(binding.span);
break;
}
}
}
- pub fn prohibit_parenthesized_params(&self, segment: &hir::PathSegment, emit_error: bool) {
- if let hir::ParenthesizedParameters(ref data) = segment.parameters {
- if emit_error {
- struct_span_err!(self.tcx().sess, data.span, E0214,
- "parenthesized parameters may only be used with a trait")
- .span_label(data.span, "only traits may use parentheses")
- .emit();
- } else {
- let msg = "parenthesized parameters may only be used with a trait";
- self.tcx().lint_node(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
- ast::CRATE_NODE_ID, data.span, msg);
- }
- }
- }
-
pub fn prohibit_projection(&self, span: Span) {
let mut err = struct_span_err!(self.tcx().sess, span, E0229,
"associated type bindings are not allowed here");
Some(trait_did) == tcx.lang_items.sync_trait() {
let segments = &bound.trait_ref.path.segments;
let parameters = &segments[segments.len() - 1].parameters;
- if !parameters.types().is_empty() {
+ if !parameters.types.is_empty() {
check_type_argument_count(tcx, bound.trait_ref.path.span,
- parameters.types().len(), &[]);
+ parameters.types.len(), &[]);
}
- if !parameters.lifetimes().is_empty() {
+ if !parameters.lifetimes.is_empty() {
report_lifetime_number_error(tcx, bound.trait_ref.path.span,
- parameters.lifetimes().len(), 0);
+ parameters.lifetimes.len(), 0);
}
true
} else {