use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee};
use rustc::ty::adjustment;
use rustc::ty::fold::{TypeFolder,TypeFoldable};
-use rustc::ty::subst::ParamSpace;
use rustc::infer::{InferCtxt, FixupError};
use rustc::util::nodemap::DefIdMap;
use write_substs_to_tcx;
wbcx.visit_closures();
wbcx.visit_liberated_fn_sigs();
wbcx.visit_fru_field_types();
- wbcx.visit_anon_types();
+ wbcx.visit_anon_types(item_id);
wbcx.visit_deferred_obligations(item_id);
}
}
// early-bound versions of them, visible from the
// outside of the function. This is needed by, and
// only populated if there are any `impl Trait`.
- free_to_bound_regions: DefIdMap<ty::Region>
+ free_to_bound_regions: DefIdMap<&'gcx ty::Region>
}
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
return wbcx;
}
+ let gcx = fcx.tcx.global_tcx();
let free_substs = fcx.parameter_environment.free_substs;
- for &space in &ParamSpace::all() {
- for (i, r) in free_substs.regions.get_slice(space).iter().enumerate() {
- match *r {
- ty::ReFree(ty::FreeRegion {
- bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
- }) => {
- let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion {
- space: space,
- index: i as u32,
- name: name,
- });
- wbcx.free_to_bound_regions.insert(def_id, bound_region);
- }
- _ => {
- bug!("{:?} is not a free region for an early-bound lifetime", r);
- }
+ for (i, k) in free_substs.params().iter().enumerate() {
+ let r = if let Some(r) = k.as_region() {
+ r
+ } else {
+ continue;
+ };
+ match *r {
+ ty::ReFree(ty::FreeRegion {
+ bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
+ }) => {
+ let bound_region = gcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
+ index: i as u32,
+ name: name,
+ }));
+ wbcx.free_to_bound_regions.insert(def_id, bound_region);
+ }
+ _ => {
+ bug!("{:?} is not a free region for an early-bound lifetime", r);
}
}
}
self.visit_method_map_entry(ResolvingExpr(e.span),
MethodCall::expr(e.id));
- if let hir::ExprClosure(_, ref decl, _, _) = e.node {
+ if let hir::ExprClosure(_, ref decl, ..) = e.node {
for input in &decl.inputs {
self.visit_node_id(ResolvingExpr(e.span), input.id);
}
}
}
- fn visit_anon_types(&self) {
+ fn visit_anon_types(&self, item_id: ast::NodeId) {
if self.fcx.writeback_errors.get() {
return
}
+ let item_def_id = self.fcx.tcx.map.local_def_id(item_id);
+
let gcx = self.tcx().global_tcx();
for (&def_id, &concrete_ty) in self.fcx.anon_types.borrow().iter() {
let reason = ResolvingAnonTy(def_id);
// Convert the type from the function into a type valid outside
// the function, by replacing free regions with early-bound ones.
let outside_ty = gcx.fold_regions(&inside_ty, &mut false, |r, _| {
- match r {
+ match *r {
// 'static is valid everywhere.
- ty::ReStatic => ty::ReStatic,
+ ty::ReStatic |
+ ty::ReEmpty => gcx.mk_region(*r),
// Free regions that come from early-bound regions are valid.
ty::ReFree(ty::FreeRegion {
- bound_region: ty::BoundRegion::BrNamed(def_id, _, _), ..
+ bound_region: ty::BoundRegion::BrNamed(def_id, ..), ..
}) if self.free_to_bound_regions.contains_key(&def_id) => {
self.free_to_bound_regions[&def_id]
}
span_err!(self.tcx().sess, span, E0564,
"only named lifetimes are allowed in `impl Trait`, \
but `{}` was found in the type `{}`", r, inside_ty);
- ty::ReStatic
+ gcx.mk_region(ty::ReStatic)
}
ty::ReVar(_) |
- ty::ReEmpty |
ty::ReErased => {
let span = reason.span(self.tcx());
span_bug!(span, "invalid region in impl Trait: {:?}", r);
}
});
- gcx.tcache.borrow_mut().insert(def_id, ty::TypeScheme {
+ gcx.register_item_type(def_id, ty::TypeScheme {
ty: outside_ty,
- generics: ty::Generics::empty()
+ generics: gcx.lookup_generics(item_def_id)
});
}
}
}
}
- fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+ fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
match self.infcx.fully_resolve(&r) {
Ok(r) => r,
Err(e) => {
self.report_error(e);
- ty::ReStatic
+ self.tcx.mk_region(ty::ReStatic)
}
}
}