rollup merge of #18630 : nikomatsakis/purge-the-bars

This commit is contained in:
Alex Crichton 2014-11-06 13:31:18 -08:00
commit 76d2abe0e7
45 changed files with 954 additions and 630 deletions

View file

@ -57,7 +57,6 @@ register_diagnostics!(
E0044,
E0045,
E0046,
E0047,
E0049,
E0050,
E0051,
@ -111,7 +110,6 @@ register_diagnostics!(
E0108,
E0109,
E0110,
E0113,
E0116,
E0117,
E0118,
@ -145,5 +143,6 @@ register_diagnostics!(
E0163,
E0164,
E0165,
E0166
E0166,
E0167
)

View file

@ -138,7 +138,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool {
// to handle on-demand instantiation of functions via
// foo::<bar> in a const. Currently that is only done on
// a path in trans::callee that only works in block contexts.
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
if !pth.segments.iter().all(|segment| segment.parameters.is_empty()) {
span_err!(v.tcx.sess, e.span, E0013,
"paths in constants may only refer to items without \
type parameters");

View file

@ -16,7 +16,6 @@ use std::collections::HashMap;
use syntax::ast::*;
use syntax::ast_util::{walk_pat};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::owned_slice::OwnedSlice;
pub type PatIdMap = HashMap<Ident, NodeId>;
@ -133,8 +132,7 @@ pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> Path {
global: false,
segments: path.last().map(|elem| PathSegment {
identifier: Ident::new(elem.name()),
lifetimes: vec!(),
types: OwnedSlice::empty()
parameters: PathParameters::none(),
}).into_iter().collect(),
span: DUMMY_SP,
})

View file

@ -27,7 +27,6 @@ use syntax::ast_map;
use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::owned_slice::OwnedSlice;
use syntax::visit;
use syntax::visit::Visitor;
@ -945,8 +944,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
debug!("privacy - ident item {}", id);
let seg = ast::PathSegment {
identifier: name,
lifetimes: Vec::new(),
types: OwnedSlice::empty(),
parameters: ast::PathParameters::none(),
};
let segs = vec![seg];
let path = ast::Path {

View file

@ -40,7 +40,7 @@ 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::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
use syntax::ast::{TypeImplItem, UnboxedFnTyParamBound, UnnamedField};
use syntax::ast::{TypeImplItem, UnnamedField};
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::{Visibility};
@ -4523,41 +4523,6 @@ impl<'a> Resolver<'a> {
TraitTyParamBound(ref tref) => {
self.resolve_trait_reference(id, tref, reference_type)
}
UnboxedFnTyParamBound(ref unboxed_function) => {
match self.resolve_path(unboxed_function.ref_id,
&unboxed_function.path,
TypeNS,
true) {
None => {
let path_str = self.path_names_to_string(
&unboxed_function.path);
self.resolve_error(unboxed_function.path.span,
format!("unresolved trait `{}`",
path_str).as_slice())
}
Some(def) => {
match def {
(DefTrait(_), _) => {
self.record_def(unboxed_function.ref_id, def);
}
_ => {
let msg =
format!("`{}` is not a trait",
self.path_names_to_string(
&unboxed_function.path));
self.resolve_error(unboxed_function.path.span,
msg.as_slice());
}
}
}
}
for argument in unboxed_function.decl.inputs.iter() {
self.resolve_type(&*argument.ty);
}
self.resolve_type(&*unboxed_function.decl.output);
}
RegionTyParamBound(..) => {}
}
}
@ -4951,12 +4916,12 @@ impl<'a> Resolver<'a> {
if path.segments
.iter()
.any(|s| !s.lifetimes.is_empty()) {
.any(|s| s.parameters.has_lifetimes()) {
span_err!(self.session, path.span, E0157,
"lifetime parameters are not allowed on this type");
} else if path.segments
.iter()
.any(|s| s.types.len() > 0) {
.any(|s| !s.parameters.is_empty()) {
span_err!(self.session, path.span, E0153,
"type parameters are not allowed on this type");
}
@ -5234,7 +5199,7 @@ impl<'a> Resolver<'a> {
// Check the types in the path pattern.
for ty in path.segments
.iter()
.flat_map(|s| s.types.iter()) {
.flat_map(|s| s.parameters.types().into_iter()) {
self.resolve_type(&**ty);
}
}
@ -5340,7 +5305,7 @@ impl<'a> Resolver<'a> {
namespace: Namespace,
check_ribs: bool) -> Option<(Def, LastPrivate)> {
// First, resolve the types.
for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
self.resolve_type(&**ty);
}

View file

@ -204,9 +204,6 @@ impl<'a> LifetimeContext<'a> {
ast::TraitTyParamBound(ref trait_ref) => {
self.visit_trait_ref(trait_ref);
}
ast::UnboxedFnTyParamBound(ref fn_decl) => {
self.visit_unboxed_fn_ty_param_bound(&**fn_decl);
}
ast::RegionTyParamBound(ref lifetime) => {
self.visit_lifetime_ref(lifetime);
}
@ -226,18 +223,6 @@ impl<'a> LifetimeContext<'a> {
})
}
fn visit_unboxed_fn_ty_param_bound(&mut self,
bound: &ast::UnboxedFnBound) {
self.with(|scope, f| {
f(LateScope(bound.ref_id, &bound.lifetimes, scope))
}, |v| {
for argument in bound.decl.inputs.iter() {
v.visit_ty(&*argument.ty);
}
v.visit_ty(&*bound.decl.output);
})
}
/// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
fn visit_fn_decl(&mut self,
n: ast::NodeId,

View file

@ -705,7 +705,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
ast::TraitTyParamBound(ref trait_ref) => {
trait_ref
}
ast::UnboxedFnTyParamBound(..) | ast::RegionTyParamBound(..) => {
ast::RegionTyParamBound(..) => {
continue;
}
};

View file

@ -1836,11 +1836,7 @@ pub fn trans_closure(ccx: &CrateContext,
NotUnboxedClosure => monomorphized_arg_types,
// Tuple up closure argument types for the "rust-call" ABI.
IsUnboxedClosure => vec![if monomorphized_arg_types.is_empty() {
ty::mk_nil()
} else {
ty::mk_tup(ccx.tcx(), monomorphized_arg_types)
}]
IsUnboxedClosure => vec![ty::mk_tup_or_nil(ccx.tcx(), monomorphized_arg_types)]
};
for monomorphized_arg_type in monomorphized_arg_types.iter() {
debug!("trans_closure: monomorphized_arg_type: {}",

View file

@ -625,7 +625,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef {
}
ast::ExprPath(ref pth) => {
// Assert that there are no type parameters in this path.
assert!(pth.segments.iter().all(|seg| seg.types.is_empty()));
assert!(pth.segments.iter().all(|seg| !seg.parameters.has_types()));
let opt_def = cx.tcx().def_map.borrow().find_copy(&e.id);
match opt_def {

View file

@ -1838,6 +1838,14 @@ pub fn mk_slice(cx: &ctxt, r: Region, tm: mt) -> t {
pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) }
pub fn mk_tup_or_nil(cx: &ctxt, ts: Vec<t>) -> t {
if ts.len() == 0 {
ty::mk_nil()
} else {
mk_t(cx, ty_tup(ts))
}
}
pub fn mk_closure(cx: &ctxt, fty: ClosureTy) -> t {
mk_t(cx, ty_closure(box fty))
}

View file

@ -59,7 +59,7 @@ use middle::subst::{VecPerParamSpace};
use middle::ty;
use middle::typeck::lookup_def_tcx;
use middle::typeck::infer;
use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope};
use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope, BindingRscope};
use middle::typeck::rscope;
use middle::typeck::TypeAndSubsts;
use middle::typeck;
@ -207,15 +207,16 @@ pub fn opt_ast_region_to_region<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
}
fn ast_path_substs<'tcx,AC,RS>(
this: &AC,
rscope: &RS,
decl_def_id: ast::DefId,
decl_generics: &ty::Generics,
self_ty: Option<ty::t>,
associated_ty: Option<ty::t>,
path: &ast::Path)
-> Substs
where AC: AstConv<'tcx>, RS: RegionScope
this: &AC,
rscope: &RS,
decl_def_id: ast::DefId,
decl_generics: &ty::Generics,
self_ty: Option<ty::t>,
associated_ty: Option<ty::t>,
path: &ast::Path,
binder_id: ast::NodeId)
-> Substs
where AC: AstConv<'tcx>, RS: RegionScope
{
/*!
* Given a path `path` that refers to an item `I` with the
@ -236,45 +237,51 @@ fn ast_path_substs<'tcx,AC,RS>(
assert!(decl_generics.regions.all(|d| d.space == TypeSpace));
assert!(decl_generics.types.all(|d| d.space != FnSpace));
let (regions, types) = match path.segments.last().unwrap().parameters {
ast::AngleBracketedParameters(ref data) =>
angle_bracketed_parameters(this, rscope, data),
ast::ParenthesizedParameters(ref data) =>
parenthesized_parameters(this, binder_id, data),
};
// If the type is parameterized by the this region, then replace this
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
let expected_num_region_params = decl_generics.regions.len(TypeSpace);
let supplied_num_region_params = path.segments.last().unwrap().lifetimes.len();
let supplied_num_region_params = regions.len();
let regions = if expected_num_region_params == supplied_num_region_params {
path.segments.last().unwrap().lifetimes.iter().map(
|l| ast_region_to_region(this.tcx(), l)).collect::<Vec<_>>()
regions
} else {
let anon_regions =
rscope.anon_regions(path.span, expected_num_region_params);
if supplied_num_region_params != 0 || anon_regions.is_err() {
span_err!(tcx.sess, path.span, E0107,
"wrong number of lifetime parameters: expected {}, found {}",
expected_num_region_params, supplied_num_region_params);
"wrong number of lifetime parameters: expected {}, found {}",
expected_num_region_params, supplied_num_region_params);
}
match anon_regions {
Ok(v) => v.into_iter().collect(),
Err(_) => Vec::from_fn(expected_num_region_params,
|_| ty::ReStatic) // hokey
|_| ty::ReStatic) // hokey
}
};
// Convert the type parameters supplied by the user.
let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
let supplied_ty_param_count = types.len();
let formal_ty_param_count =
ty_param_defs.iter()
.take_while(|x| !ty::is_associated_type(tcx, x.def_id))
.count();
.take_while(|x| !ty::is_associated_type(tcx, x.def_id))
.count();
let required_ty_param_count =
ty_param_defs.iter()
.take_while(|x| {
x.default.is_none() &&
!ty::is_associated_type(tcx, x.def_id)
})
.count();
.take_while(|x| {
x.default.is_none() &&
!ty::is_associated_type(tcx, x.def_id)
})
.count();
if supplied_ty_param_count < required_ty_param_count {
let expected = if required_ty_param_count < formal_ty_param_count {
"expected at least"
@ -282,10 +289,10 @@ fn ast_path_substs<'tcx,AC,RS>(
"expected"
};
this.tcx().sess.span_fatal(path.span,
format!("wrong number of type arguments: {} {}, found {}",
expected,
required_ty_param_count,
supplied_ty_param_count).as_slice());
format!("wrong number of type arguments: {} {}, found {}",
expected,
required_ty_param_count,
supplied_ty_param_count).as_slice());
} else if supplied_ty_param_count > formal_ty_param_count {
let expected = if required_ty_param_count < formal_ty_param_count {
"expected at most"
@ -293,10 +300,10 @@ fn ast_path_substs<'tcx,AC,RS>(
"expected"
};
this.tcx().sess.span_fatal(path.span,
format!("wrong number of type arguments: {} {}, found {}",
expected,
formal_ty_param_count,
supplied_ty_param_count).as_slice());
format!("wrong number of type arguments: {} {}, found {}",
expected,
formal_ty_param_count,
supplied_ty_param_count).as_slice());
}
if supplied_ty_param_count > required_ty_param_count
@ -307,13 +314,7 @@ fn ast_path_substs<'tcx,AC,RS>(
"add #![feature(default_type_params)] to the crate attributes to enable");
}
let tps = path.segments
.iter()
.flat_map(|s| s.types.iter())
.map(|a_t| ast_ty_to_ty(this, rscope, &**a_t))
.collect();
let mut substs = Substs::new_type(tps, regions);
let mut substs = Substs::new_type(types, regions);
match self_ty {
None => {
@ -354,7 +355,47 @@ fn ast_path_substs<'tcx,AC,RS>(
param.def_id))
}
substs
return substs;
fn angle_bracketed_parameters<'tcx, AC, RS>(this: &AC,
rscope: &RS,
data: &ast::AngleBracketedParameterData)
-> (Vec<ty::Region>, Vec<ty::t>)
where AC: AstConv<'tcx>, RS: RegionScope
{
let regions: Vec<_> =
data.lifetimes.iter()
.map(|l| ast_region_to_region(this.tcx(), l))
.collect();
let types: Vec<_> =
data.types.iter()
.map(|t| ast_ty_to_ty(this, rscope, &**t))
.collect();
(regions, types)
}
fn parenthesized_parameters<'tcx,AC>(this: &AC,
binder_id: ast::NodeId,
data: &ast::ParenthesizedParameterData)
-> (Vec<ty::Region>, Vec<ty::t>)
where AC: AstConv<'tcx>
{
let binding_rscope = BindingRscope::new(binder_id);
let inputs = data.inputs.iter()
.map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
.collect();
let input_ty = ty::mk_tup_or_nil(this.tcx(), inputs);
let output = match data.output {
Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty),
None => ty::mk_nil()
};
(Vec::new(), vec![input_ty, output])
}
}
pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC,
@ -362,7 +403,8 @@ pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC,
trait_def_id: ast::DefId,
self_ty: Option<ty::t>,
associated_type: Option<ty::t>,
path: &ast::Path)
path: &ast::Path,
binder_id: ast::NodeId)
-> Rc<ty::TraitRef>
where AC: AstConv<'tcx>,
RS: RegionScope {
@ -375,7 +417,8 @@ pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC,
&trait_def.generics,
self_ty,
associated_type,
path)
path,
binder_id)
})
}
@ -383,8 +426,10 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
this: &AC,
rscope: &RS,
did: ast::DefId,
path: &ast::Path)
-> TypeAndSubsts {
path: &ast::Path,
binder_id: ast::NodeId)
-> TypeAndSubsts
{
let tcx = this.tcx();
let ty::Polytype {
generics,
@ -397,7 +442,8 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
&generics,
None,
None,
path);
path,
binder_id);
let ty = decl_ty.subst(tcx, &substs);
TypeAndSubsts { substs: substs, ty: ty }
}
@ -407,24 +453,29 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
/// and/or region variables are substituted.
///
/// This is used when checking the constructor in struct literals.
pub fn ast_path_to_ty_relaxed<'tcx, AC: AstConv<'tcx>,
RS:RegionScope>(
this: &AC,
rscope: &RS,
did: ast::DefId,
path: &ast::Path)
-> TypeAndSubsts {
pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
this: &AC,
rscope: &RS,
did: ast::DefId,
path: &ast::Path,
binder_id: ast::NodeId)
-> TypeAndSubsts
where AC : AstConv<'tcx>, RS : RegionScope
{
let tcx = this.tcx();
let ty::Polytype {
generics,
ty: decl_ty
} = this.get_item_ty(did);
let substs = if (generics.has_type_params(TypeSpace) ||
generics.has_region_params(TypeSpace)) &&
path.segments.iter().all(|s| {
s.lifetimes.len() == 0 && s.types.len() == 0
}) {
let wants_params =
generics.has_type_params(TypeSpace) || generics.has_region_params(TypeSpace);
let needs_defaults =
wants_params &&
path.segments.iter().all(|s| s.parameters.is_empty());
let substs = if needs_defaults {
let type_params = Vec::from_fn(generics.types.len(TypeSpace),
|_| this.ty_infer(path.span));
let region_params =
@ -433,7 +484,7 @@ pub fn ast_path_to_ty_relaxed<'tcx, AC: AstConv<'tcx>,
Substs::new(VecPerParamSpace::params_from_type(type_params),
VecPerParamSpace::params_from_type(region_params))
} else {
ast_path_substs(this, rscope, did, &generics, None, None, path)
ast_path_substs(this, rscope, did, &generics, None, None, path, binder_id)
};
let ty = decl_ty.subst(tcx, &substs);
@ -450,14 +501,14 @@ fn check_path_args(tcx: &ty::ctxt,
path: &ast::Path,
flags: uint) {
if (flags & NO_TPS) != 0u {
if !path.segments.iter().all(|s| s.types.is_empty()) {
if path.segments.iter().any(|s| s.parameters.has_types()) {
span_err!(tcx.sess, path.span, E0109,
"type parameters are not allowed on this type");
}
}
if (flags & NO_REGIONS) != 0u {
if !path.segments.last().unwrap().lifetimes.is_empty() {
if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
span_err!(tcx.sess, path.span, E0110,
"region parameters are not allowed on this type");
}
@ -538,29 +589,23 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
// FIXME(#12938): This is a hack until we have full support for
// DST.
match a_def {
def::DefTy(did, _) | def::DefStruct(did)
if Some(did) == this.tcx().lang_items.owned_box() => {
if path.segments
.iter()
.flat_map(|s| s.types.iter())
.count() > 1 {
span_err!(this.tcx().sess, path.span, E0047,
"`Box` has only one type parameter");
def::DefTy(did, _) |
def::DefStruct(did) if Some(did) == this.tcx().lang_items.owned_box() => {
let ty = ast_path_to_ty(this, rscope, did, path, id).ty;
match ty::get(ty).sty {
ty::ty_struct(struct_def_id, ref substs) => {
assert_eq!(struct_def_id, did);
assert_eq!(substs.types.len(TypeSpace), 1);
let referent_ty = *substs.types.get(TypeSpace, 0);
Some(ty::mk_uniq(this.tcx(), referent_ty))
}
_ => {
this.tcx().sess.span_bug(
path.span,
format!("converting `Box` to `{}`",
ty.repr(this.tcx()))[]);
}
}
for inner_ast_type in path.segments
.iter()
.flat_map(|s| s.types.iter()) {
return Some(mk_pointer(this,
rscope,
ast::MutImmutable,
&**inner_ast_type,
Uniq,
|typ| ty::mk_uniq(this.tcx(), typ)));
}
span_err!(this.tcx().sess, path.span, E0113,
"not enough type parameters supplied to `Box<T>`");
Some(ty::mk_err())
}
_ => None
}
@ -575,15 +620,6 @@ enum PointerTy {
Uniq
}
impl PointerTy {
fn default_region(&self) -> ty::Region {
match *self {
Uniq => ty::ReStatic,
RPtr(r) => r,
}
}
}
pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>,
RS:RegionScope>(
this: &AC,
@ -603,11 +639,7 @@ pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>,
.map(|input| {
ast_ty_to_ty(this, rscope, &*input.ty)
}).collect::<Vec<_>>();
let input_tuple = if input_types.len() == 0 {
ty::mk_nil()
} else {
ty::mk_tup(this.tcx(), input_types)
};
let input_tuple = ty::mk_tup_or_nil(this.tcx(), input_types);
let output_type = ast_ty_to_ty(this, rscope, &*decl.output);
let mut substs = Substs::new_type(vec!(input_tuple, output_type),
Vec::new());
@ -646,31 +678,6 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
let ty = ast_ty_to_ty(this, rscope, &**ty);
return constr(ty::mk_vec(tcx, ty, None));
}
ast::TyUnboxedFn(ref unboxed_function) => {
let ty::TraitRef {
def_id,
substs
} = trait_ref_for_unboxed_function(this,
rscope,
unboxed_function.kind,
&*unboxed_function.decl,
None);
let r = ptr_ty.default_region();
let tr = ty::mk_trait(this.tcx(),
def_id,
substs,
ty::region_existential_bound(r));
match ptr_ty {
Uniq => {
return ty::mk_uniq(this.tcx(), tr);
}
RPtr(r) => {
return ty::mk_rptr(this.tcx(),
r,
ty::mt {mutbl: a_seq_mutbl, ty: tr});
}
}
}
ast::TyPath(ref path, ref opt_bounds, id) => {
// Note that the "bounds must be empty if path is not a trait"
// restriction is enforced in the below case for ty_path, which
@ -693,7 +700,8 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
trait_def_id,
None,
None,
path);
path,
id);
let bounds = match *opt_bounds {
None => {
conv_existential_bounds(this,
@ -771,7 +779,12 @@ fn associated_ty_to_ty<'tcx,AC,RS>(this: &AC,
trait_did,
None,
Some(for_type),
trait_path);
trait_path,
ast::DUMMY_NODE_ID); // *see below
// * The trait in a qualified path cannot be "higher-ranked" and
// hence cannot use the parenthetical sugar, so the binder-id is
// irrelevant.
debug!("associated_ty_to_ty(trait_ref={})",
trait_ref.repr(this.tcx()));
@ -894,11 +907,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
ty::mk_closure(tcx, fn_decl)
}
ast::TyUnboxedFn(..) => {
tcx.sess.span_err(ast_ty.span,
"cannot use unboxed functions here");
ty::mk_err()
}
ast::TyPath(ref path, ref bounds, id) => {
let a_def = match tcx.def_map.borrow().get(&id) {
None => {
@ -925,7 +933,8 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
trait_def_id,
None,
None,
path);
path,
id);
let empty_bounds: &[ast::TyParamBound] = &[];
let ast_bounds = match *bounds {
Some(ref b) => b.as_slice(),
@ -942,7 +951,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
bounds)
}
def::DefTy(did, _) | def::DefStruct(did) => {
ast_path_to_ty(this, rscope, did, path).ty
ast_path_to_ty(this, rscope, did, path, id).ty
}
def::DefTyParam(space, id, n) => {
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
@ -1377,8 +1386,7 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
let PartitionedBounds { builtin_bounds,
trait_bounds,
region_bounds,
unboxed_fn_ty_bounds } =
region_bounds } =
partition_bounds(this.tcx(), span, ast_bound_refs.as_slice());
if !trait_bounds.is_empty() {
@ -1389,13 +1397,6 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
as closure or object bounds").as_slice());
}
if !unboxed_fn_ty_bounds.is_empty() {
this.tcx().sess.span_err(
span,
format!("only the builtin traits can be used \
as closure or object bounds").as_slice());
}
// The "main trait refs", rather annoyingly, have no type
// specified for the `Self` parameter of the trait. The reason for
// this is that they are, after all, *existential* types, and
@ -1524,7 +1525,6 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
pub struct PartitionedBounds<'a> {
pub builtin_bounds: ty::BuiltinBounds,
pub trait_bounds: Vec<&'a ast::TraitRef>,
pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnBound>,
pub region_bounds: Vec<&'a ast::Lifetime>,
}
@ -1542,7 +1542,6 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
let mut builtin_bounds = ty::empty_builtin_bounds();
let mut region_bounds = Vec::new();
let mut trait_bounds = Vec::new();
let mut unboxed_fn_ty_bounds = Vec::new();
let mut trait_def_ids = HashMap::new();
for &ast_bound in ast_bounds.iter() {
match *ast_bound {
@ -1587,9 +1586,6 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
ast::RegionTyParamBound(ref l) => {
region_bounds.push(l);
}
ast::UnboxedFnTyParamBound(ref unboxed_function) => {
unboxed_fn_ty_bounds.push(&**unboxed_function);
}
}
}
@ -1597,7 +1593,6 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
builtin_bounds: builtin_bounds,
trait_bounds: trait_bounds,
region_bounds: region_bounds,
unboxed_fn_ty_bounds: unboxed_fn_ty_bounds
}
}

View file

@ -3481,11 +3481,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
// Tuple up the arguments and insert the resulting function type into
// the `unboxed_closures` table.
fn_ty.sig.inputs = if fn_ty.sig.inputs.len() == 0 {
vec![ty::mk_nil()]
} else {
vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.inputs)]
};
fn_ty.sig.inputs = vec![ty::mk_tup_or_nil(fcx.tcx(), fn_ty.sig.inputs)];
let kind = match kind {
ast::FnUnboxedClosureKind => ty::FnUnboxedClosureKind,
@ -4478,7 +4474,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
let type_and_substs = astconv::ast_path_to_ty_relaxed(fcx,
fcx.infcx(),
struct_id,
path);
path,
expr.id);
match fcx.mk_subty(false,
infer::Misc(path.span),
actual_structure_type,
@ -5339,6 +5336,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
Some(space) => {
push_explicit_parameters_from_segment_to_substs(fcx,
space,
path.span,
type_defs,
region_defs,
segment,
@ -5374,13 +5372,13 @@ pub fn instantiate_path(fcx: &FnCtxt,
fcx: &FnCtxt,
segment: &ast::PathSegment)
{
for typ in segment.types.iter() {
for typ in segment.parameters.types().iter() {
span_err!(fcx.tcx().sess, typ.span, E0085,
"type parameters may not appear here");
break;
}
for lifetime in segment.lifetimes.iter() {
for lifetime in segment.parameters.lifetimes().iter() {
span_err!(fcx.tcx().sess, lifetime.span, E0086,
"lifetime parameters may not appear here");
break;
@ -5390,6 +5388,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
fn push_explicit_parameters_from_segment_to_substs(
fcx: &FnCtxt,
space: subst::ParamSpace,
span: Span,
type_defs: &VecPerParamSpace<ty::TypeParameterDef>,
region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
segment: &ast::PathSegment,
@ -5412,10 +5411,31 @@ pub fn instantiate_path(fcx: &FnCtxt,
* span of the N+1'th parameter.
*/
match segment.parameters {
ast::AngleBracketedParameters(ref data) => {
push_explicit_angle_bracketed_parameters_from_segment_to_substs(
fcx, space, type_defs, region_defs, data, substs);
}
ast::ParenthesizedParameters(ref data) => {
push_explicit_parenthesized_parameters_from_segment_to_substs(
fcx, space, span, type_defs, data, substs);
}
}
}
fn push_explicit_angle_bracketed_parameters_from_segment_to_substs(
fcx: &FnCtxt,
space: subst::ParamSpace,
type_defs: &VecPerParamSpace<ty::TypeParameterDef>,
region_defs: &VecPerParamSpace<ty::RegionParameterDef>,
data: &ast::AngleBracketedParameterData,
substs: &mut Substs)
{
{
let type_count = type_defs.len(space);
assert_eq!(substs.types.len(space), 0);
for (i, typ) in segment.types.iter().enumerate() {
for (i, typ) in data.types.iter().enumerate() {
let t = fcx.to_ty(&**typ);
if i < type_count {
substs.types.push(space, t);
@ -5424,7 +5444,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
"too many type parameters provided: \
expected at most {} parameter(s), \
found {} parameter(s)",
type_count, segment.types.len());
type_count, data.types.len());
substs.types.truncate(space, 0);
}
}
@ -5433,7 +5453,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
{
let region_count = region_defs.len(space);
assert_eq!(substs.regions().len(space), 0);
for (i, lifetime) in segment.lifetimes.iter().enumerate() {
for (i, lifetime) in data.lifetimes.iter().enumerate() {
let r = ast_region_to_region(fcx.tcx(), lifetime);
if i < region_count {
substs.mut_regions().push(space, r);
@ -5442,13 +5462,59 @@ pub fn instantiate_path(fcx: &FnCtxt,
"too many lifetime parameters provided: \
expected {} parameter(s), found {} parameter(s)",
region_count,
segment.lifetimes.len());
data.lifetimes.len());
substs.mut_regions().truncate(space, 0);
}
}
}
}
fn push_explicit_parenthesized_parameters_from_segment_to_substs(
fcx: &FnCtxt,
space: subst::ParamSpace,
span: Span,
type_defs: &VecPerParamSpace<ty::TypeParameterDef>,
data: &ast::ParenthesizedParameterData,
substs: &mut Substs)
{
/*!
* As with
* `push_explicit_angle_bracketed_parameters_from_segment_to_substs`,
* but intended for `Foo(A,B) -> C` form. This expands to
* roughly the same thing as `Foo<(A,B),C>`. One important
* difference has to do with the treatment of anonymous
* regions, which are translated into bound regions (NYI).
*/
let type_count = type_defs.len(space);
if type_count < 2 {
span_err!(fcx.tcx().sess, span, E0167,
"parenthesized form always supplies 2 type parameters, \
but only {} parameter(s) were expected",
type_count);
}
let input_tys: Vec<ty::t> =
data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect();
let tuple_ty =
ty::mk_tup_or_nil(fcx.tcx(), input_tys);
if type_count >= 1 {
substs.types.push(space, tuple_ty);
}
let output_ty: Option<ty::t> =
data.output.as_ref().map(|ty| fcx.to_ty(&**ty));
let output_ty =
output_ty.unwrap_or(ty::mk_nil());
if type_count >= 2 {
substs.types.push(space, output_ty);
}
}
fn adjust_type_parameters(
fcx: &FnCtxt,
span: Span,

View file

@ -638,7 +638,7 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
let mut bounds = bounds.chain(ty_param.unbound.iter());
for bound in bounds {
match *bound {
ast::TraitTyParamBound(..) | ast::UnboxedFnTyParamBound(..) => {
ast::TraitTyParamBound(..) => {
// According to accepted RFC #XXX, we should
// eventually accept these, but it will not be
// part of this PR. Still, convert to warning to
@ -1340,7 +1340,8 @@ pub fn instantiate_trait_ref<'tcx,AC>(this: &AC,
trait_did,
Some(self_ty),
associated_type,
&ast_trait_ref.path);
&ast_trait_ref.path,
ast_trait_ref.ref_id);
this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id,
trait_ref.clone());
@ -1355,20 +1356,6 @@ pub fn instantiate_trait_ref<'tcx,AC>(this: &AC,
}
}
pub fn instantiate_unboxed_fn_ty<'tcx,AC>(this: &AC,
unboxed_function: &ast::UnboxedFnTy,
param_ty: ty::ParamTy)
-> Rc<ty::TraitRef>
where AC: AstConv<'tcx> {
let rscope = ExplicitRscope;
let param_ty = param_ty.to_ty(this.tcx());
Rc::new(astconv::trait_ref_for_unboxed_function(this,
&rscope,
unboxed_function.kind,
&*unboxed_function.decl,
Some(param_ty)))
}
fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc<ty::TraitDef> {
if trait_id.krate != ast::LOCAL_CRATE {
return ty::lookup_trait_def(ccx.tcx, trait_id)
@ -1878,7 +1865,6 @@ fn ty_generics<'tcx,AC>(this: &AC,
// In the above example, `ast_trait_ref` is `Iterator`.
let ast_trait_ref = match *bound {
ast::TraitTyParamBound(ref r) => r,
ast::UnboxedFnTyParamBound(..) => { continue; }
ast::RegionTyParamBound(..) => { continue; }
};
@ -2056,45 +2042,8 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
merge_param_bounds(this.tcx(), param_ty, ast_bounds, where_clause);
let astconv::PartitionedBounds { builtin_bounds,
trait_bounds,
region_bounds,
unboxed_fn_ty_bounds } =
region_bounds } =
astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice());
let unboxed_fn_ty_bounds = unboxed_fn_ty_bounds.into_iter().map(|b| {
let trait_id = (*this.tcx().def_map.borrow())[b.ref_id].def_id();
let mut kind = None;
for &(lang_item, this_kind) in [
(this.tcx().lang_items.fn_trait(), ast::FnUnboxedClosureKind),
(this.tcx().lang_items.fn_mut_trait(),
ast::FnMutUnboxedClosureKind),
(this.tcx().lang_items.fn_once_trait(),
ast::FnOnceUnboxedClosureKind)
].iter() {
if Some(trait_id) == lang_item {
kind = Some(this_kind);
break
}
}
let kind = match kind {
Some(kind) => kind,
None => {
this.tcx().sess.span_err(b.path.span,
"unboxed function trait must be one \
of `Fn`, `FnMut`, or `FnOnce`");
ast::FnMutUnboxedClosureKind
}
};
let rscope = ExplicitRscope;
let param_ty = param_ty.to_ty(this.tcx());
Rc::new(astconv::trait_ref_for_unboxed_function(this,
&rscope,
kind,
&*b.decl,
Some(param_ty)))
});
let trait_bounds: Vec<Rc<ty::TraitRef>> =
trait_bounds.into_iter()
.map(|b| {
@ -2103,7 +2052,6 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
param_ty.to_ty(this.tcx()),
Some(param_ty.to_ty(this.tcx())))
})
.chain(unboxed_fn_ty_bounds)
.collect();
let region_bounds: Vec<ty::Region> =
region_bounds.into_iter()

View file

@ -1102,13 +1102,11 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
// be passing down a map.
ast::RegionTyParamBound(lt)
}
&ast::UnboxedFnTyParamBound(ref unboxed_function_type) => {
ast::UnboxedFnTyParamBound((*unboxed_function_type).clone())
}
&ast::TraitTyParamBound(ref tr) => {
let last_seg = tr.path.segments.last().unwrap();
let mut insert = Vec::new();
for (i, lt) in last_seg.lifetimes.iter().enumerate() {
let lifetimes = last_seg.parameters.lifetimes();
for (i, lt) in lifetimes.iter().enumerate() {
if region_names.contains(&lt.name) {
insert.push(i);
}
@ -1116,7 +1114,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
let rebuild_info = RebuildPathInfo {
path: &tr.path,
indexes: insert,
expected: last_seg.lifetimes.len(),
expected: lifetimes.len(),
anon_nums: &HashSet::new(),
region_names: region_names
};
@ -1257,7 +1255,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
let expected =
generics.regions.len(subst::TypeSpace);
let lifetimes =
&path.segments.last().unwrap().lifetimes;
path.segments.last().unwrap().parameters.lifetimes();
let mut insert = Vec::new();
if lifetimes.len() == 0 {
let anon = self.cur_anon.get();
@ -1357,7 +1355,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
fn rebuild_path(&self,
rebuild_info: RebuildPathInfo,
lifetime: ast::Lifetime)
-> ast::Path {
-> ast::Path
{
let RebuildPathInfo {
path,
indexes,
@ -1367,37 +1366,48 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
} = rebuild_info;
let last_seg = path.segments.last().unwrap();
let mut new_lts = Vec::new();
if last_seg.lifetimes.len() == 0 {
// traverse once to see if there's a need to insert lifetime
let need_insert = range(0, expected).any(|i| {
indexes.contains(&i)
});
if need_insert {
for i in range(0, expected) {
if indexes.contains(&i) {
new_lts.push(lifetime);
} else {
new_lts.push(self.life_giver.give_lifetime());
let new_parameters = match last_seg.parameters {
ast::ParenthesizedParameters(..) => {
last_seg.parameters.clone()
}
ast::AngleBracketedParameters(ref data) => {
let mut new_lts = Vec::new();
if data.lifetimes.len() == 0 {
// traverse once to see if there's a need to insert lifetime
let need_insert = range(0, expected).any(|i| {
indexes.contains(&i)
});
if need_insert {
for i in range(0, expected) {
if indexes.contains(&i) {
new_lts.push(lifetime);
} else {
new_lts.push(self.life_giver.give_lifetime());
}
}
}
} else {
for (i, lt) in data.lifetimes.iter().enumerate() {
if indexes.contains(&i) {
new_lts.push(lifetime);
} else {
new_lts.push(*lt);
}
}
}
let new_types = data.types.map(|t| {
self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names)
});
ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
lifetimes: new_lts,
types: new_types
})
}
} else {
for (i, lt) in last_seg.lifetimes.iter().enumerate() {
if indexes.contains(&i) {
new_lts.push(lifetime);
} else {
new_lts.push(*lt);
}
}
}
let new_types = last_seg.types.map(|t| {
self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names)
});
};
let new_seg = ast::PathSegment {
identifier: last_seg.identifier,
lifetimes: new_lts,
types: new_types,
parameters: new_parameters
};
let mut new_segs = Vec::new();
new_segs.push_all(path.segments.init());