use middle::implicator::object_region_bounds;
use middle::resolve_lifetime as rl;
use middle::privacy::{AllPublic, LastMod};
-use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
+use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace};
use middle::traits;
use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
use middle::ty_fold;
use require_c_abi_if_variadic;
-use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
+use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope,
ElisionFailureInfo, ElidedLifetime};
use util::common::{ErrorReported, FN_OUTPUT_NAME};
use std::slice;
use syntax::{abi, ast, ast_util};
use syntax::codemap::{Span, Pos};
+use syntax::feature_gate::emit_feature_err;
use syntax::parse::token;
use syntax::print::pprust;
}
/// What type should we use when a type is omitted?
- fn ty_infer(&self, span: Span) -> Ty<'tcx>;
+ fn ty_infer(&self,
+ param_and_substs: Option<ty::TypeParameterDef<'tcx>>,
+ substs: Option<&mut Substs<'tcx>>,
+ space: Option<ParamSpace>,
+ span: Span) -> Ty<'tcx>;
/// Projecting an associated type from a (potentially)
/// higher-ranked trait reference is more complicated, because of
// they were optional (e.g. paths inside expressions).
let mut type_substs = if param_mode == PathParamMode::Optional &&
types_provided.is_empty() {
- (0..formal_ty_param_count).map(|_| this.ty_infer(span)).collect()
+ let mut substs = region_substs.clone();
+ ty_param_defs
+ .iter()
+ .map(|p| this.ty_infer(Some(p.clone()), Some(&mut substs), Some(TypeSpace), span))
+ .collect()
} else {
types_provided
};
// For now, require that parenthetical notation be used
// only with `Fn()` etc.
if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
- span_err!(this.tcx().sess, span, E0215,
- "angle-bracket notation is not stable when \
- used with the `Fn` family of traits, use parentheses");
- fileline_help!(this.tcx().sess, span,
- "add `#![feature(unboxed_closures)]` to \
- the crate attributes to enable");
+ emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
+ "unboxed_closures", span,
+ "\
+ the precise format of `Fn`-family traits' type parameters is \
+ subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
}
convert_angle_bracketed_parameters(this, rscope, span, &trait_def.generics, data)
// For now, require that parenthetical notation be used
// only with `Fn()` etc.
if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
- span_err!(this.tcx().sess, span, E0216,
- "parenthetical notation is only stable when \
- used with the `Fn` family of traits");
- fileline_help!(this.tcx().sess, span,
- "add `#![feature(unboxed_closures)]` to \
- the crate attributes to enable");
+ emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
+ "unboxed_closures", span,
+ "\
+ parenthetical notation is only stable when used with `Fn`-family traits");
}
convert_parenthesized_parameters(this, rscope, span, &trait_def.generics, data)
let candidate = try!(one_bound_for_assoc_type(tcx,
candidates,
&trait_ref.to_string(),
- &token::get_name(binding.item_name),
+ &binding.item_name.as_str(),
binding.span));
Ok(ty::Binder(ty::ProjectionPredicate { // <-------------------------+
one_bound_for_assoc_type(tcx,
suitable_bounds,
- &token::get_name(ty_param_name),
- &token::get_name(assoc_name),
+ &ty_param_name.as_str(),
+ &assoc_name.as_str(),
span)
}
(_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
// `Self` in an impl of a trait - we have a concrete self type and a
// trait reference.
- match tcx.map.expect_item(impl_id).node {
- ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) => {
- if this.ensure_super_predicates(span, trait_did).is_err() {
- return (tcx.types.err, ty_path_def);
- }
+ let trait_ref = tcx.impl_trait_ref(ast_util::local_def(impl_id)).unwrap();
+ let trait_ref = if let Some(free_substs) = this.get_free_substs() {
+ trait_ref.subst(tcx, free_substs)
+ } else {
+ trait_ref
+ };
- let trait_segment = &trait_ref.path.segments.last().unwrap();
- let trait_ref = ast_path_to_mono_trait_ref(this,
- &ExplicitRscope,
- span,
- PathParamMode::Explicit,
- trait_did,
- Some(ty),
- trait_segment);
-
- let candidates: Vec<ty::PolyTraitRef> =
- traits::supertraits(tcx, ty::Binder(trait_ref.clone()))
- .filter(|r| this.trait_defines_associated_type_named(r.def_id(),
- assoc_name))
- .collect();
-
- match one_bound_for_assoc_type(tcx,
- candidates,
- "Self",
- &token::get_name(assoc_name),
- span) {
- Ok(bound) => bound,
- Err(ErrorReported) => return (tcx.types.err, ty_path_def),
- }
- }
- _ => unreachable!()
+ if this.ensure_super_predicates(span, trait_did).is_err() {
+ return (tcx.types.err, ty_path_def);
+ }
+
+ let candidates: Vec<ty::PolyTraitRef> =
+ traits::supertraits(tcx, ty::Binder(trait_ref))
+ .filter(|r| this.trait_defines_associated_type_named(r.def_id(),
+ assoc_name))
+ .collect();
+
+ match one_bound_for_assoc_type(tcx,
+ candidates,
+ "Self",
+ &assoc_name.as_str(),
+ span) {
+ Ok(bound) => bound,
+ Err(ErrorReported) => return (tcx.types.err, ty_path_def),
}
}
- (&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
+ (&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
assert_eq!(trait_did.krate, ast::LOCAL_CRATE);
match find_bound_for_assoc_item(this,
trait_did.node,
span,
&ty.to_string(),
"Trait",
- &token::get_name(assoc_name));
+ &assoc_name.as_str());
return (tcx.types.err, ty_path_def);
}
};
span,
"Type",
&path_str,
- &token::get_ident(item_segment.identifier));
+ &item_segment.identifier.name.as_str());
return tcx.types.err;
};
// values in a ExprClosure, or as
// the type of local variables. Both of these cases are
// handled specially and will not descend into this routine.
- this.ty_infer(ast_ty.span)
+ this.ty_infer(None, None, None, ast_ty.span)
+ }
+ ast::TyMac(_) => {
+ tcx.sess.span_bug(ast_ty.span, "unexpanded type macro found conversion")
}
};
{
match a.ty.node {
ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
- ast::TyInfer => this.ty_infer(a.ty.span),
+ ast::TyInfer => this.ty_infer(None, None, None, a.ty.span),
_ => ast_ty_to_ty(this, rscope, &*a.ty),
}
}
let output_ty = match decl.output {
ast::Return(ref output) if output.node == ast::TyInfer =>
- ty::FnConverging(this.ty_infer(output.span)),
+ ty::FnConverging(this.ty_infer(None, None, None, output.span)),
ast::Return(ref output) =>
ty::FnConverging(convert_ty_with_lifetime_elision(this,
implied_output_region,
_ if is_infer && expected_ret_ty.is_some() =>
expected_ret_ty.unwrap(),
_ if is_infer =>
- ty::FnConverging(this.ty_infer(decl.output.span())),
+ ty::FnConverging(this.ty_infer(None, None, None, decl.output.span())),
ast::Return(ref output) =>
ty::FnConverging(ast_ty_to_ty(this, &rb, &**output)),
ast::DefaultReturn(..) => unreachable!(),