diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index bc0c61ad7ad..3ca12959246 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -121,7 +121,7 @@ use syntax::visit; // Main entry point pub fn collect_item_types(tcx: &ty::ctxt) { - let ccx = &CollectCtxt { tcx: tcx }; + let ccx = &CrateCtxt { tcx: tcx }; match ccx.tcx.lang_items.ty_desc() { Some(id) => { collect_intrinsic_type(ccx, id); } @@ -141,17 +141,22 @@ pub fn collect_item_types(tcx: &ty::ctxt) { /////////////////////////////////////////////////////////////////////////// -struct CollectCtxt<'a,'tcx:'a> { +struct CrateCtxt<'a,'tcx:'a> { tcx: &'a ty::ctxt<'tcx>, } +#[allow(dead_code)] // just temporary, for generics +struct ItemCtxt<'a,'tcx:'a> { + ccx: &'a CrateCtxt<'a,'tcx>, + generics: &'a ty::Generics<'tcx>, +} + /////////////////////////////////////////////////////////////////////////// // Zeroth phase: collect types of intrinsics -fn collect_intrinsic_type(ccx: &CollectCtxt, +fn collect_intrinsic_type(ccx: &CrateCtxt, lang_item: ast::DefId) { - let ty::TypeScheme { ty, .. } = - ccx.get_item_type_scheme(lang_item); + let ty::TypeScheme { ty, .. } = type_scheme_of_def_id(ccx, lang_item); ccx.tcx.intrinsic_defs.borrow_mut().insert(lang_item, ty); } @@ -161,7 +166,7 @@ fn collect_intrinsic_type(ccx: &CollectCtxt, // know later when parsing field defs. struct CollectTraitDefVisitor<'a, 'tcx: 'a> { - ccx: &'a CollectCtxt<'a, 'tcx> + ccx: &'a CrateCtxt<'a, 'tcx> } impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> { @@ -182,7 +187,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> { // Second phase: collection proper. struct CollectItemTypesVisitor<'a, 'tcx: 'a> { - ccx: &'a CollectCtxt<'a, 'tcx> + ccx: &'a CrateCtxt<'a, 'tcx> } impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { @@ -199,42 +204,41 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // Utility types and common code for the above passes. +impl<'a,'tcx> CrateCtxt<'a,'tcx> { + fn icx(&'a self, generics: &'a ty::Generics<'tcx>) -> ItemCtxt<'a,'tcx> { + ItemCtxt { ccx: self, generics: generics } + } + + fn method_ty(&self, method_id: ast::NodeId) -> Rc> { + let def_id = local_def(method_id); + match self.tcx.impl_or_trait_items.borrow()[def_id] { + ty::MethodTraitItem(ref mty) => mty.clone(), + ty::TypeTraitItem(..) => { + self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id)); + } + } + } +} + pub trait ToTy<'tcx> { fn to_ty(&self, rs: &RS, ast_ty: &ast::Ty) -> Ty<'tcx>; } -impl<'a,'tcx> ToTy<'tcx> for CollectCtxt<'a,'tcx> { +impl<'a,'tcx> ToTy<'tcx> for ItemCtxt<'a,'tcx> { fn to_ty(&self, rs: &RS, ast_ty: &ast::Ty) -> Ty<'tcx> { ast_ty_to_ty(self, rs, ast_ty) } } -impl<'a, 'tcx> AstConv<'tcx> for CollectCtxt<'a, 'tcx> { - fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx } +impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> { + fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx } fn get_item_type_scheme(&self, id: ast::DefId) -> ty::TypeScheme<'tcx> { - if id.krate != ast::LOCAL_CRATE { - return ty::lookup_item_type(self.tcx, id); - } - - match self.tcx.map.find(id.node) { - Some(ast_map::NodeItem(item)) => { - type_scheme_of_item(self, &*item) - } - Some(ast_map::NodeForeignItem(foreign_item)) => { - let abi = self.tcx.map.get_foreign_abi(id.node); - type_scheme_of_foreign_item(self, &*foreign_item, abi) - } - x => { - self.tcx.sess.bug(&format!("unexpected sort of node \ - in get_item_type_scheme(): {:?}", - x)); - } - } + type_scheme_of_def_id(self.ccx, id) } fn get_trait_def(&self, id: ast::DefId) -> Rc> { - get_trait_def(self, id) + get_trait_def(self.ccx, id) } fn ty_infer(&self, span: Span) -> Ty<'tcx> { @@ -253,11 +257,12 @@ impl<'a, 'tcx> AstConv<'tcx> for CollectCtxt<'a, 'tcx> { } } -fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, enum_scheme: ty::TypeScheme<'tcx>, enum_predicates: ty::GenericPredicates<'tcx>, variants: &[P]) { let tcx = ccx.tcx; + let icx = ccx.icx(&enum_scheme.generics); // Create a set of parameter types shared among all the variants. for variant in variants { @@ -268,8 +273,8 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, let result_ty = match variant.node.kind { ast::TupleVariantKind(ref args) if args.len() > 0 => { let rs = ExplicitRscope; - let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, &*va.ty)).collect(); - ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[..], enum_scheme.ty) + let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect(); + ty::mk_ctor_fn(tcx, variant_def_id, &input_tys, enum_scheme.ty) } ast::TupleVariantKind(_) => { @@ -294,7 +299,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id: ast::NodeId, trait_def: &ty::TraitDef<'tcx>, trait_predicates: &ty::GenericPredicates<'tcx>) { @@ -393,7 +398,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } - fn make_method_ty<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, m: &ty::Method<'tcx>) { + fn make_method_ty<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, m: &ty::Method<'tcx>) { ccx.tcx.tcache.borrow_mut().insert( m.def_id, TypeScheme { @@ -405,7 +410,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, m.predicates.clone()); } - fn ty_method_of_trait_method<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, + fn ty_method_of_trait_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id: ast::NodeId, trait_generics: &ty::Generics<'tcx>, trait_bounds: &ty::GenericPredicates<'tcx>, @@ -417,7 +422,8 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, m_generics: &ast::Generics, m_unsafety: &ast::Unsafety, m_decl: &ast::FnDecl) - -> ty::Method<'tcx> { + -> ty::Method<'tcx> + { let ty_generics = ty_generics_for_fn_or_method(ccx, m_generics, @@ -431,7 +437,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, let (fty, explicit_self_category) = { let trait_self_ty = ty::mk_self_type(ccx.tcx); - astconv::ty_of_method(ccx, + astconv::ty_of_method(&ccx.icx(&ty_generics), *m_unsafety, trait_self_ty, m_explicit_self, @@ -454,12 +460,14 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn convert_field<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, - struct_generics: &ty::Generics<'tcx>, - struct_predicates: &ty::GenericPredicates<'tcx>, - v: &ast::StructField, - origin: ast::DefId) -> ty::field_ty { - let tt = ccx.to_ty(&ExplicitRscope, &*v.node.ty); +fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + struct_generics: &ty::Generics<'tcx>, + struct_predicates: &ty::GenericPredicates<'tcx>, + v: &ast::StructField, + origin: ast::DefId) + -> ty::field_ty +{ + let tt = ccx.icx(struct_generics).to_ty(&ExplicitRscope, &*v.node.ty); write_ty_to_tcx(ccx.tcx, v.node.id, tt); /* add the field to the tcache */ @@ -491,7 +499,7 @@ fn convert_field<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn convert_associated_type<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_def: &ty::TraitDef<'tcx>, associated_type: &ast::AssociatedType) { @@ -504,11 +512,10 @@ fn convert_associated_type<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, ccx.tcx .impl_or_trait_items .borrow_mut() - .insert(associated_type.def_id, - ty::TypeTraitItem(associated_type)); + .insert(associated_type.def_id, ty::TypeTraitItem(associated_type)); } -fn convert_methods<'a,'tcx,'i,I>(ccx: &CollectCtxt<'a, 'tcx>, +fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, container: ImplOrTraitItemContainer, ms: I, untransformed_rcvr_ty: Ty<'tcx>, @@ -559,7 +566,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CollectCtxt<'a, 'tcx>, .insert(mty.def_id, ty::MethodTraitItem(mty)); } - fn ty_of_method<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, + fn ty_of_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, container: ImplOrTraitItemContainer, m: &ast::Method, untransformed_rcvr_ty: Ty<'tcx>, @@ -578,7 +585,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CollectCtxt<'a, 'tcx>, &m_ty_generics, rcvr_ty_predicates.clone()); - let (fty, explicit_self_category) = astconv::ty_of_method(ccx, + let (fty, explicit_self_category) = astconv::ty_of_method(&ccx.icx(&m_ty_generics), m.pe_unsafety(), untransformed_rcvr_ty, m.pe_explicit_self(), @@ -603,7 +610,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn ensure_no_ty_param_bounds(ccx: &CollectCtxt, +fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, span: Span, generics: &ast::Generics, thing: &'static str) { @@ -632,7 +639,7 @@ fn ensure_no_ty_param_bounds(ccx: &CollectCtxt, } } -fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { +fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let tcx = ccx.tcx; debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id); match it.node { @@ -671,7 +678,7 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { debug!("convert: impl_bounds={:?}", ty_predicates); - let selfty = ccx.to_ty(&ExplicitRscope, &**selfty); + let selfty = ccx.icx(&ty_generics).to_ty(&ExplicitRscope, &**selfty); write_ty_to_tcx(tcx, it.id, selfty); tcx.tcache.borrow_mut().insert(local_def(it.id), @@ -695,12 +702,6 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { for impl_item in impl_items { match *impl_item { ast::MethodImplItem(ref method) => { - let body_id = method.pe_body().id; - check_method_self_type(ccx, - &BindingRscope::new(), - selfty, - method.pe_explicit_self(), - body_id); methods.push(&**method); } ast::TypeImplItem(ref typedef) => { @@ -709,7 +710,7 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { "associated items are not allowed in inherent impls"); } - let typ = ccx.to_ty(&ExplicitRscope, &*typedef.typ); + let typ = ccx.icx(&ty_generics).to_ty(&ExplicitRscope, &*typedef.typ); tcx.tcache.borrow_mut().insert(local_def(typedef.id), TypeScheme { generics: ty::Generics::empty(), @@ -741,8 +742,23 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { &ty_predicates, parent_visibility); + for impl_item in impl_items { + match *impl_item { + ast::MethodImplItem(ref method) => { + let body_id = method.pe_body().id; + check_method_self_type(ccx, + &BindingRscope::new(), + ccx.method_ty(method.id), + selfty, + method.pe_explicit_self(), + body_id); + } + ast::TypeImplItem(..) => { } + } + } + if let Some(ref trait_ref) = *opt_trait_ref { - astconv::instantiate_trait_ref(ccx, + astconv::instantiate_trait_ref(&ccx.icx(&ty_generics), &ExplicitRscope, trait_ref, Some(it.id), @@ -754,44 +770,18 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { generics, local_def(it.id)); }, - ast::ItemTrait(_, _, _, ref trait_methods) => { + ast::ItemTrait(_, _, _, ref trait_items) => { let trait_def = trait_def_of_item(ccx, it); convert_trait_predicates(ccx, it); let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id)); debug!("convert: trait_bounds={:?}", trait_predicates); - for trait_method in trait_methods { - let self_type = ty::mk_self_type(tcx); - match *trait_method { - ast::RequiredMethod(ref type_method) => { - let rscope = BindingRscope::new(); - check_method_self_type(ccx, - &rscope, - self_type, - &type_method.explicit_self, - it.id) - } - ast::ProvidedMethod(ref method) => { - check_method_self_type(ccx, - &BindingRscope::new(), - self_type, - method.pe_explicit_self(), - it.id) - } - ast::TypeTraitItem(ref associated_type) => { - convert_associated_type(ccx, - &*trait_def, - &**associated_type); - } - } - } - // Run convert_methods on the provided methods. let untransformed_rcvr_ty = ty::mk_self_type(tcx); convert_methods(ccx, TraitContainer(local_def(it.id)), - trait_methods.iter().filter_map(|m| match *m { + trait_items.iter().filter_map(|m| match *m { ast::RequiredMethod(_) => None, ast::ProvidedMethod(ref m) => Some(&**m), ast::TypeTraitItem(_) => None, @@ -805,6 +795,36 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { // convert_methods produces a tcache entry that is wrong for // static trait methods. This is somewhat unfortunate. collect_trait_methods(ccx, it.id, &*trait_def, &trait_predicates); + + // This must be done after `collect_trait_methods` so that + // we have a method type stored for every method. + for trait_item in trait_items { + let self_type = ty::mk_self_type(tcx); + match *trait_item { + ast::RequiredMethod(ref type_method) => { + let rscope = BindingRscope::new(); + check_method_self_type(ccx, + &rscope, + ccx.method_ty(type_method.id), + self_type, + &type_method.explicit_self, + it.id) + } + ast::ProvidedMethod(ref method) => { + check_method_self_type(ccx, + &BindingRscope::new(), + ccx.method_ty(method.id), + self_type, + method.pe_explicit_self(), + it.id) + } + ast::TypeTraitItem(ref associated_type) => { + convert_associated_type(ccx, + &*trait_def, + &**associated_type); + } + } + } }, ast::ItemStruct(ref struct_def, _) => { // Write the class type. @@ -827,7 +847,7 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) { } } -fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, struct_def: &ast::StructDef, scheme: ty::TypeScheme<'tcx>, predicates: ty::GenericPredicates<'tcx>, @@ -897,7 +917,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn get_trait_def<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn get_trait_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id: ast::DefId) -> Rc> { let tcx = ccx.tcx; @@ -915,7 +935,7 @@ fn get_trait_def<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) -> Rc> { @@ -959,6 +979,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, // supertraits: let bounds = compute_bounds(ccx, + &ty_generics, self_param_ty, bounds, SizedByDefault::No, @@ -992,7 +1013,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, return trait_def; - fn mk_trait_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, + fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &ast::Generics) -> subst::Substs<'tcx> { @@ -1025,7 +1046,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } } -fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Item) { +fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) { let tcx = ccx.tcx; let trait_def = trait_def_of_item(ccx, it); @@ -1044,7 +1065,8 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Ite let super_predicates = ty::predicates(ccx.tcx, self_param_ty, &trait_def.bounds); - let assoc_predicates = predicates_for_associated_types(ccx, &trait_def.trait_ref, items); + let assoc_predicates = predicates_for_associated_types(ccx, &trait_def.generics, + &trait_def.trait_ref, items); // `ty_generic_bounds` below will consider the bounds on the type // parameters (including `Self`) and the explicit where-clauses, @@ -1075,7 +1097,8 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Ite return; - fn predicates_for_associated_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, + fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + generics: &ty::Generics<'tcx>, self_trait_ref: &Rc>, trait_items: &[ast::TraitItem]) -> Vec> @@ -1095,6 +1118,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Ite assoc_type_def.ident.name); let bounds = compute_bounds(ccx, + generics, assoc_ty, &*assoc_type_def.bounds, SizedByDefault::Yes, @@ -1106,7 +1130,31 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Ite } } -fn type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, + def_id: ast::DefId) + -> ty::TypeScheme<'tcx> +{ + if def_id.krate != ast::LOCAL_CRATE { + return ty::lookup_item_type(ccx.tcx, def_id); + } + + match ccx.tcx.map.find(def_id.node) { + Some(ast_map::NodeItem(item)) => { + type_scheme_of_item(ccx, &*item) + } + Some(ast_map::NodeForeignItem(foreign_item)) => { + let abi = ccx.tcx.map.get_foreign_abi(def_id.node); + type_scheme_of_foreign_item(ccx, &*foreign_item, abi) + } + x => { + ccx.tcx.sess.bug(&format!("unexpected sort of node \ + in get_item_type_scheme(): {:?}", + x)); + } + } +} + +fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &ast::Item) -> ty::TypeScheme<'tcx> { @@ -1116,27 +1164,27 @@ fn type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, } -fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, - it: &ast::Item) - -> ty::TypeScheme<'tcx> +fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, + it: &ast::Item) + -> ty::TypeScheme<'tcx> { let tcx = ccx.tcx; match it.node { ast::ItemStatic(ref t, _, _) | ast::ItemConst(ref t, _) => { - let ty = ccx.to_ty(&ExplicitRscope, &**t); + let ty = ccx.icx(&ty::Generics::empty()).to_ty(&ExplicitRscope, &**t); ty::TypeScheme { ty: ty, generics: ty::Generics::empty() } } ast::ItemFn(ref decl, unsafety, abi, ref generics, _) => { let ty_generics = ty_generics_for_fn_or_method(ccx, generics, ty::Generics::empty()); - let tofd = astconv::ty_of_bare_fn(ccx, unsafety, abi, &**decl); + let tofd = astconv::ty_of_bare_fn(&ccx.icx(&ty_generics), unsafety, abi, &**decl); let ty = ty::mk_bare_fn(tcx, Some(local_def(it.id)), tcx.mk_bare_fn(tofd)); ty::TypeScheme { ty: ty, generics: ty_generics } } ast::ItemTy(ref t, ref generics) => { - let ty = ccx.to_ty(&ExplicitRscope, &**t); let ty_generics = ty_generics_for_type_or_impl(ccx, generics); + let ty = ccx.icx(&ty_generics).to_ty(&ExplicitRscope, &**t); ty::TypeScheme { ty: ty, generics: ty_generics } } ast::ItemEnum(_, ref generics) => { @@ -1168,7 +1216,7 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, } } -fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>) { @@ -1234,18 +1282,18 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, } fn type_scheme_of_foreign_item<'a, 'tcx>( - ccx: &CollectCtxt<'a, 'tcx>, + ccx: &CrateCtxt<'a, 'tcx>, it: &ast::ForeignItem, abi: abi::Abi) -> ty::TypeScheme<'tcx> { - memoized(&ccx.tcx().tcache, + memoized(&ccx.tcx.tcache, local_def(it.id), |_| compute_type_scheme_of_foreign_item(ccx, it, abi)) } fn compute_type_scheme_of_foreign_item<'a, 'tcx>( - ccx: &CollectCtxt<'a, 'tcx>, + ccx: &CrateCtxt<'a, 'tcx>, it: &ast::ForeignItem, abi: abi::Abi) -> ty::TypeScheme<'tcx> @@ -1257,13 +1305,13 @@ fn compute_type_scheme_of_foreign_item<'a, 'tcx>( ast::ForeignItemStatic(ref t, _) => { ty::TypeScheme { generics: ty::Generics::empty(), - ty: ast_ty_to_ty(ccx, &ExplicitRscope, t) + ty: ast_ty_to_ty(&ccx.icx(&ty::Generics::empty()), &ExplicitRscope, t) } } } } -fn convert_foreign_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::ForeignItem) { // For reasons I cannot fully articulate, I do so hate the AST @@ -1292,7 +1340,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, assert!(prev_predicates.is_none()); } -fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &ast::Generics) -> ty::Generics<'tcx> { ty_generics(ccx, @@ -1303,7 +1351,7 @@ fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, ty::Generics::empty()) } -fn ty_generic_bounds_for_type_or_impl<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn ty_generic_bounds_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ty_generics: &ty::Generics<'tcx>, generics: &ast::Generics) -> ty::GenericPredicates<'tcx> @@ -1315,7 +1363,7 @@ fn ty_generic_bounds_for_type_or_impl<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, &generics.where_clause) } -fn ty_generics_for_trait<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id: ast::NodeId, substs: &'tcx subst::Substs<'tcx>, ast_generics: &ast::Generics) @@ -1364,7 +1412,7 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, return generics; } -fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, generics: &ast::Generics, base_generics: ty::Generics<'tcx>) -> ty::Generics<'tcx> @@ -1378,7 +1426,7 @@ fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, base_generics) } -fn ty_generic_bounds_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn ty_generic_bounds_for_fn_or_method<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, generics: &ast::Generics, ty_generics: &ty::Generics<'tcx>, base: ty::GenericPredicates<'tcx>) @@ -1392,7 +1440,7 @@ fn ty_generic_bounds_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, } // Add the Sized bound, unless the type parameter is marked as `?Sized`. -fn add_unsized_bound<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn add_unsized_bound<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, bounds: &mut ty::BuiltinBounds, ast_bounds: &[ast::TyParamBound], span: Span) @@ -1438,7 +1486,7 @@ fn add_unsized_bound<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, } } -fn ty_generic_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn ty_generic_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, space: subst::ParamSpace, generics: &ty::Generics<'tcx>, base: ty::GenericPredicates<'tcx>, @@ -1465,7 +1513,9 @@ fn ty_generic_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, for predicate in &where_clause.predicates { match predicate { &ast::WherePredicate::BoundPredicate(ref bound_pred) => { - let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &*bound_pred.bounded_ty); + let ty = ast_ty_to_ty(&ccx.icx(generics), + &ExplicitRscope, + &*bound_pred.bounded_ty); for bound in &*bound_pred.bounds { match bound { @@ -1473,7 +1523,7 @@ fn ty_generic_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, let mut projections = Vec::new(); let trait_ref = astconv::instantiate_poly_trait_ref( - ccx, + &ccx.icx(generics), &ExplicitRscope, poly_trait_ref, Some(ty), @@ -1517,7 +1567,7 @@ fn ty_generic_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, return result; } -fn ty_generics<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, space: subst::ParamSpace, lifetime_defs: &[ast::LifetimeDef], types: &[ast::TyParam], @@ -1554,7 +1604,7 @@ fn ty_generics<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, result } -fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, space: subst::ParamSpace, param: &ast::TyParam, index: u32, @@ -1569,6 +1619,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, let param_ty = ty::ParamTy::new(space, index, param.ident.name); let bounds = compute_bounds(ccx, + &ty::Generics::empty(), param_ty.to_ty(ccx.tcx), ¶m.bounds, SizedByDefault::Yes, @@ -1576,7 +1627,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, let default = match param.default { None => None, Some(ref path) => { - let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &**path); + let ty = ast_ty_to_ty(&ccx.icx(&ty::Generics::empty()), &ExplicitRscope, &**path); let cur_idx = index; ty::walk_ty(ty, |t| { @@ -1705,7 +1756,8 @@ enum SizedByDefault { Yes, No } /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the /// built-in trait (formerly known as kind): Send. -fn compute_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn compute_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, + generics: &ty::Generics<'tcx>, param_ty: ty::Ty<'tcx>, ast_bounds: &[ast::TyParamBound], sized_by_default: SizedByDefault, @@ -1713,6 +1765,7 @@ fn compute_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, -> ty::ParamBounds<'tcx> { let mut param_bounds = conv_param_bounds(ccx, + generics, span, param_ty, ast_bounds); @@ -1734,7 +1787,7 @@ fn compute_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, param_bounds } -fn check_bounds_compatible<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn check_bounds_compatible<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, param_ty: Ty<'tcx>, param_bounds: &ty::ParamBounds<'tcx>, span: Span) { @@ -1743,7 +1796,7 @@ fn check_bounds_compatible<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, ccx.tcx, ¶m_bounds.trait_bounds, |trait_ref| { - let trait_def = ccx.get_trait_def(trait_ref.def_id()); + let trait_def = get_trait_def(ccx, trait_ref.def_id()); if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) { span_err!(ccx.tcx.sess, span, E0129, "incompatible bounds on `{}`, \ @@ -1756,7 +1809,8 @@ fn check_bounds_compatible<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, } } -fn conv_param_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, +fn conv_param_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, + generics: &ty::Generics<'tcx>, span: Span, param_ty: ty::Ty<'tcx>, ast_bounds: &[ast::TyParamBound]) @@ -1774,7 +1828,7 @@ fn conv_param_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, let trait_bounds: Vec = trait_bounds.into_iter() .map(|bound| { - astconv::instantiate_poly_trait_ref(ccx, + astconv::instantiate_poly_trait_ref(&ccx.icx(generics), &ExplicitRscope, bound, Some(param_ty), @@ -1796,7 +1850,7 @@ fn conv_param_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>, } fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>( - ccx: &CollectCtxt<'a, 'tcx>, + ccx: &CrateCtxt<'a, 'tcx>, decl: &ast::FnDecl, ast_generics: &ast::Generics, abi: abi::Abi) @@ -1818,12 +1872,12 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>( let rb = BindingRscope::new(); let input_tys = decl.inputs .iter() - .map(|a| ty_of_arg(ccx, &rb, a, None)) + .map(|a| ty_of_arg(&ccx.icx(&ty_generics), &rb, a, None)) .collect(); let output = match decl.output { ast::Return(ref ty) => - ty::FnConverging(ast_ty_to_ty(ccx, &rb, &**ty)), + ty::FnConverging(ast_ty_to_ty(&ccx.icx(&ty_generics), &rb, &**ty)), ast::DefaultReturn(..) => ty::FnConverging(ty::mk_nil(ccx.tcx)), ast::NoReturn(..) => @@ -1847,7 +1901,7 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>( } } -fn mk_item_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, +fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty_generics: &ty::Generics<'tcx>) -> subst::Substs<'tcx> { @@ -1869,15 +1923,16 @@ fn mk_item_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, /// comes back to check after the fact that explicit type the user /// wrote actually matches what the pre-defined option said. fn check_method_self_type<'a, 'tcx, RS:RegionScope>( - ccx: &CollectCtxt<'a, 'tcx>, + ccx: &CrateCtxt<'a, 'tcx>, rs: &RS, + method_type: Rc>, required_type: Ty<'tcx>, explicit_self: &ast::ExplicitSelf, body_id: ast::NodeId) { let tcx = ccx.tcx; if let ast::SelfExplicit(ref ast_type, _) = explicit_self.node { - let typ = ccx.to_ty(rs, &**ast_type); + let typ = ccx.icx(&method_type.generics).to_ty(rs, &**ast_type); let base_type = match typ.sty { ty::ty_ptr(tm) | ty::ty_rptr(_, tm) => tm.ty, ty::ty_uniq(typ) => typ,