diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index a322fcb3fa1..2662d6ef190 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -5824,7 +5824,8 @@ pub fn erase_late_bound_regions
(
{
/*!
* Replace any late-bound regions bound in `value` with `'static`.
- * Useful in trans.
+ * Useful in trans but also method lookup and a few other places
+ * where precise region relationships are not required.
*/
replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 39474a99f6d..9c4a532790d 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -519,8 +519,9 @@ pub fn get_res_dtor(ccx: &CrateContext,
let name = csearch::get_symbol(&ccx.sess().cstore, did);
let class_ty = ty::lookup_item_type(tcx, parent_id).ty.subst(tcx, substs);
let llty = type_of_dtor(ccx, class_ty);
- let dtor_ty = ty::mk_ctor_fn(ccx.tcx(), ast::DUMMY_NODE_ID,
- &[glue::get_drop_glue_type(ccx, t)], ty::mk_nil(ccx.tcx()));
+ let dtor_ty = ty::mk_ctor_fn(ccx.tcx(),
+ &[glue::get_drop_glue_type(ccx, t)],
+ ty::mk_nil(ccx.tcx()));
get_extern_fn(ccx,
&mut *ccx.externs().borrow_mut(),
name.as_slice(),
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 8e3ae6ee359..cbd0d756f08 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -432,6 +432,8 @@ pub fn trans_fn_ref_with_substs(
substs.repr(tcx));
assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
+ assert!(substs.types.all(|t| !ty::type_has_escaping_regions(*t)));
+ let substs = substs.erase_regions();
// Load the info for the appropriate trait if necessary.
match ty::trait_of_item(tcx, def_id) {
@@ -470,8 +472,9 @@ pub fn trans_fn_ref_with_substs(
default methods");
// Compute the first substitution
- let first_subst = make_substs_for_receiver_types(
- tcx, &*trait_ref, &*method);
+ let first_subst =
+ make_substs_for_receiver_types(tcx, &*trait_ref, &*method)
+ .erase_regions();
// And compose them
let new_substs = first_subst.subst(tcx, &substs);
@@ -661,7 +664,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
trans_fn_ref_with_substs_to_callee(bcx,
did,
0,
- subst::Substs::empty())
+ subst::Substs::trans_empty())
},
ArgVals(args),
dest)
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index 139087507ff..3cb823aec34 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -486,7 +486,7 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
let llfn = get_or_create_declaration_if_unboxed_closure(
bcx,
closure_id,
- &bcx.fcx.param_substs.substs).unwrap();
+ bcx.fcx.param_substs.substs()).unwrap();
let function_type = (*bcx.tcx().unboxed_closures.borrow())[closure_id]
.closure_type
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index d06cfa4a027..21cf3138661 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -191,10 +191,21 @@ pub type ExternMap = FnvHashMap;
// Here `self_ty` is the real type of the self parameter to this method. It
// will only be set in the case of default methods.
pub struct param_substs {
- pub substs: subst::Substs,
+ substs: subst::Substs,
}
impl param_substs {
+ pub fn new(substs: subst::Substs) -> param_substs {
+ assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
+ assert!(substs.types.all(|t| !ty::type_has_params(*t)));
+ assert!(substs.types.all(|t| !ty::type_has_escaping_regions(*t)));
+ param_substs { substs: substs.erase_regions() }
+ }
+
+ pub fn substs(&self) -> &subst::Substs {
+ &self.substs
+ }
+
pub fn empty() -> param_substs {
param_substs {
substs: subst::Substs::trans_empty(),
@@ -822,6 +833,8 @@ pub fn fulfill_obligation(ccx: &CrateContext,
None => { }
}
+ debug!("trans fulfill_obligation: trait_ref={}", trait_ref.repr(ccx.tcx()));
+
ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id);
let infcx = infer::new_infer_ctxt(tcx);
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index e3e36ee53fd..65fd9566760 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -1410,7 +1410,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
file_metadata: DIFile,
name_to_append_suffix_to: &mut String)
-> DIArray {
- let self_type = param_substs.substs.self_ty();
+ let self_type = param_substs.substs().self_ty();
// Only true for static default methods:
let has_self_type = self_type.is_some();
@@ -1467,7 +1467,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
}
// Handle other generic parameters
- let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
+ let actual_types = param_substs.substs().types.get_slice(subst::FnSpace);
for (index, &ast::TyParam{ ident, .. }) in generics.ty_params.iter().enumerate() {
let actual_type = actual_types[index];
// Add actual type name to <...> clause of function name
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 2b7c3d0c24f..40a4d6047aa 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -329,12 +329,12 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bcx.ty_to_string(unsized_ty)).as_slice())
},
&ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
- let substs = principal.substs.with_self_ty(unsized_ty);
+ let substs = principal.substs.with_self_ty(unsized_ty).erase_regions();
let trait_ref =
Rc::new(ty::TraitRef { def_id: principal.def_id,
substs: substs });
let trait_ref =
- trait_ref.subst(bcx.tcx(), &bcx.fcx.param_substs.substs);
+ trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs.substs());
let box_ty = mk_ty(unsized_ty);
PointerCast(bcx,
meth::get_vtable(bcx, box_ty, trait_ref),
@@ -1122,7 +1122,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
.map(|t| (*t).clone())
.unwrap();
let trait_ref =
- trait_ref.subst(bcx.tcx(), &bcx.fcx.param_substs.substs);
+ trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs.substs());
let datum = unpack_datum!(bcx, trans(bcx, &**val));
meth::trans_trait_cast(bcx, datum, expr.id,
trait_ref, dest)
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index 3ca37f9e355..f86a0994bf9 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -536,7 +536,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
let _icx = push_ctxt("foreign::build_foreign_fn");
let fnty = ty::node_id_to_type(ccx.tcx(), id);
- let mty = fnty.subst(ccx.tcx(), ¶m_substs.substs);
+ let mty = fnty.subst(ccx.tcx(), param_substs.substs());
let tys = foreign_types_for_fn_ty(ccx, mty);
unsafe { // unsafe because we call LLVM operations
@@ -558,7 +558,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
let _icx = push_ctxt("foreign::foreign::build_rust_fn");
let tcx = ccx.tcx();
let t = ty::node_id_to_type(tcx, id).subst(
- ccx.tcx(), ¶m_substs.substs);
+ ccx.tcx(), param_substs.substs());
let ps = ccx.tcx().map.with_path(id, |path| {
let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index cceea96d4c1..5188ca77350 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -287,8 +287,9 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
val, *ty);
}
- let dtor_ty = ty::mk_ctor_fn(variant_cx.tcx(), ast::DUMMY_NODE_ID,
- &[get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil(bcx.tcx()));
+ let dtor_ty = ty::mk_ctor_fn(bcx.tcx(),
+ &[get_drop_glue_type(bcx.ccx(), t)],
+ ty::mk_nil(bcx.tcx()));
let (_, variant_cx) = invoke(variant_cx, dtor_addr, args, dtor_ty, None, false);
variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index a2510cbfa27..90777afff7e 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -137,8 +137,11 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}) => {
let trait_ref =
Rc::new(trait_ref.subst(bcx.tcx(),
- &bcx.fcx.param_substs.substs));
+ bcx.fcx.param_substs.substs()));
let span = bcx.tcx().map.span(method_call.expr_id);
+ debug!("method_call={} trait_ref={}",
+ method_call,
+ trait_ref.repr(bcx.tcx()));
let origin = fulfill_obligation(bcx.ccx(),
span,
(*trait_ref).clone());
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 077c1337a44..52aa81fa427 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -63,9 +63,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
None => ()
}
- let psubsts = param_substs {
- substs: (*real_substs).clone(),
- };
+ debug!("creating param_substs with real_substs={}", real_substs.repr(ccx.tcx()));
+ let psubsts = param_substs::new((*real_substs).clone());
debug!("monomorphic_fn(\
fn_id={}, \