Consistently normalize fn types after erasing lifetimes.
Fixes #23406. Fixes #23958. Fixes #29832.
This commit is contained in:
parent
4f5edf9e38
commit
82ab7079dd
13 changed files with 114 additions and 56 deletions
|
@ -142,6 +142,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
|
||||||
};
|
};
|
||||||
|
|
||||||
let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
|
let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
|
||||||
|
let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);
|
||||||
|
|
||||||
let mut attrs = llvm::AttrBuilder::new();
|
let mut attrs = llvm::AttrBuilder::new();
|
||||||
let ret_ty = fn_sig.output;
|
let ret_ty = fn_sig.output;
|
||||||
|
|
|
@ -38,6 +38,7 @@ use metadata::{csearch, encoder, loader};
|
||||||
use middle::astencode;
|
use middle::astencode;
|
||||||
use middle::cfg;
|
use middle::cfg;
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
|
use middle::infer;
|
||||||
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
||||||
use middle::weak_lang_items;
|
use middle::weak_lang_items;
|
||||||
use middle::pat_util::simple_name;
|
use middle::pat_util::simple_name;
|
||||||
|
@ -1905,7 +1906,11 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
debug!("trans_fn(param_substs={:?})", param_substs);
|
debug!("trans_fn(param_substs={:?})", param_substs);
|
||||||
let _icx = push_ctxt("trans_fn");
|
let _icx = push_ctxt("trans_fn");
|
||||||
let fn_ty = ccx.tcx().node_id_to_type(id);
|
let fn_ty = ccx.tcx().node_id_to_type(id);
|
||||||
let output_type = ccx.tcx().erase_late_bound_regions(&fn_ty.fn_ret());
|
let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty);
|
||||||
|
let sig = fn_ty.fn_sig();
|
||||||
|
let sig = ccx.tcx().erase_late_bound_regions(&sig);
|
||||||
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
|
let output_type = sig.output;
|
||||||
let abi = fn_ty.fn_abi();
|
let abi = fn_ty.fn_abi();
|
||||||
trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi,
|
trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi,
|
||||||
closure::ClosureEnv::NotClosure);
|
closure::ClosureEnv::NotClosure);
|
||||||
|
@ -1936,15 +1941,9 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||||
|
|
||||||
let ccx = bcx.fcx.ccx;
|
let ccx = bcx.fcx.ccx;
|
||||||
|
|
||||||
let result_ty = match ctor_ty.sty {
|
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
|
||||||
ty::TyBareFn(_, ref bft) => {
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
bcx.tcx().erase_late_bound_regions(&bft.sig.output()).unwrap()
|
let result_ty = sig.output.unwrap();
|
||||||
}
|
|
||||||
_ => ccx.sess().bug(
|
|
||||||
&format!("trans_enum_variant_constructor: \
|
|
||||||
unexpected ctor return type {}",
|
|
||||||
ctor_ty))
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get location to store the result. If the user does not care about
|
// Get location to store the result. If the user does not care about
|
||||||
// the result, just make a stack slot
|
// the result, just make a stack slot
|
||||||
|
@ -2026,15 +2025,10 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
|
||||||
let ctor_ty = ccx.tcx().node_id_to_type(ctor_id);
|
let ctor_ty = ccx.tcx().node_id_to_type(ctor_id);
|
||||||
let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty);
|
let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty);
|
||||||
|
|
||||||
let result_ty = match ctor_ty.sty {
|
let sig = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_sig());
|
||||||
ty::TyBareFn(_, ref bft) => {
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
ccx.tcx().erase_late_bound_regions(&bft.sig.output())
|
let arg_tys = sig.inputs;
|
||||||
}
|
let result_ty = sig.output;
|
||||||
_ => ccx.sess().bug(
|
|
||||||
&format!("trans_enum_variant_or_tuple_like_struct: \
|
|
||||||
unexpected ctor return type {}",
|
|
||||||
ctor_ty))
|
|
||||||
};
|
|
||||||
|
|
||||||
let (arena, fcx): (TypedArena<_>, FunctionContext);
|
let (arena, fcx): (TypedArena<_>, FunctionContext);
|
||||||
arena = TypedArena::new();
|
arena = TypedArena::new();
|
||||||
|
@ -2044,8 +2038,6 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
|
||||||
|
|
||||||
assert!(!fcx.needs_ret_allocas);
|
assert!(!fcx.needs_ret_allocas);
|
||||||
|
|
||||||
let arg_tys = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_args());
|
|
||||||
|
|
||||||
if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
|
if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
|
||||||
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
|
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
|
||||||
let repr = adt::represent_type(ccx, result_ty.unwrap());
|
let repr = adt::represent_type(ccx, result_ty.unwrap());
|
||||||
|
|
|
@ -25,7 +25,7 @@ use llvm::{self, ValueRef, get_params};
|
||||||
use metadata::cstore::LOCAL_CRATE;
|
use metadata::cstore::LOCAL_CRATE;
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
use middle::infer::normalize_associated_type;
|
use middle::infer;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
use middle::subst::{Substs};
|
use middle::subst::{Substs};
|
||||||
use rustc::front::map as hir_map;
|
use rustc::front::map as hir_map;
|
||||||
|
@ -304,6 +304,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let sig = tcx.erase_late_bound_regions(sig);
|
let sig = tcx.erase_late_bound_regions(sig);
|
||||||
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
|
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
|
||||||
let tuple_fn_ty = tcx.mk_fn(opt_def_id,
|
let tuple_fn_ty = tcx.mk_fn(opt_def_id,
|
||||||
tcx.mk_bare_fn(ty::BareFnTy {
|
tcx.mk_bare_fn(ty::BareFnTy {
|
||||||
|
@ -466,7 +467,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
||||||
|
|
||||||
// Type scheme of the function item (may have type params)
|
// Type scheme of the function item (may have type params)
|
||||||
let fn_type_scheme = tcx.lookup_item_type(def_id);
|
let fn_type_scheme = tcx.lookup_item_type(def_id);
|
||||||
let fn_type = normalize_associated_type(tcx, &fn_type_scheme.ty);
|
let fn_type = infer::normalize_associated_type(tcx, &fn_type_scheme.ty);
|
||||||
|
|
||||||
// Find the actual function pointer.
|
// Find the actual function pointer.
|
||||||
let mut val = {
|
let mut val = {
|
||||||
|
@ -605,8 +606,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
||||||
|
|
||||||
let (abi, ret_ty) = match callee.ty.sty {
|
let (abi, ret_ty) = match callee.ty.sty {
|
||||||
ty::TyBareFn(_, ref f) => {
|
ty::TyBareFn(_, ref f) => {
|
||||||
let output = bcx.tcx().erase_late_bound_regions(&f.sig.output());
|
let sig = bcx.tcx().erase_late_bound_regions(&f.sig);
|
||||||
(f.abi, output)
|
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
|
||||||
|
(f.abi, sig.output)
|
||||||
}
|
}
|
||||||
_ => panic!("expected bare rust fn or closure in trans_call_inner")
|
_ => panic!("expected bare rust fn or closure in trans_call_inner")
|
||||||
};
|
};
|
||||||
|
@ -826,7 +828,9 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
|
||||||
ignore_self: bool)
|
ignore_self: bool)
|
||||||
-> Block<'blk, 'tcx>
|
-> Block<'blk, 'tcx>
|
||||||
{
|
{
|
||||||
let args = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
|
let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
|
||||||
|
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
|
||||||
|
let args = sig.inputs;
|
||||||
|
|
||||||
// Translate the `self` argument first.
|
// Translate the `self` argument first.
|
||||||
if !ignore_self {
|
if !ignore_self {
|
||||||
|
@ -887,7 +891,10 @@ fn trans_overloaded_call_args<'blk, 'tcx>(
|
||||||
ignore_self: bool)
|
ignore_self: bool)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
// Translate the `self` argument first.
|
// Translate the `self` argument first.
|
||||||
let arg_tys = bcx.tcx().erase_late_bound_regions( &fn_ty.fn_args());
|
let sig = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
|
||||||
|
let sig = infer::normalize_associated_type(bcx.tcx(), &sig);
|
||||||
|
let arg_tys = sig.inputs;
|
||||||
|
|
||||||
if !ignore_self {
|
if !ignore_self {
|
||||||
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0]));
|
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0]));
|
||||||
bcx = trans_arg_datum(bcx,
|
bcx = trans_arg_datum(bcx,
|
||||||
|
@ -933,8 +940,10 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||||
debug!("trans_args(abi={})", abi);
|
debug!("trans_args(abi={})", abi);
|
||||||
|
|
||||||
let _icx = push_ctxt("trans_args");
|
let _icx = push_ctxt("trans_args");
|
||||||
let arg_tys = cx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
|
let sig = cx.tcx().erase_late_bound_regions(&fn_ty.fn_sig());
|
||||||
let variadic = fn_ty.fn_sig().0.variadic;
|
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
|
||||||
|
let arg_tys = sig.inputs;
|
||||||
|
let variadic = sig.variadic;
|
||||||
|
|
||||||
let mut bcx = cx;
|
let mut bcx = cx;
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
|
||||||
tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
|
tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
|
||||||
|
|
||||||
let sig = tcx.erase_late_bound_regions(&function_type.sig);
|
let sig = tcx.erase_late_bound_regions(&function_type.sig);
|
||||||
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
|
|
||||||
trans_closure(ccx,
|
trans_closure(ccx,
|
||||||
decl,
|
decl,
|
||||||
|
@ -371,6 +372,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||||
let lloncefn = declare::define_internal_rust_fn(ccx, &function_name,
|
let lloncefn = declare::define_internal_rust_fn(ccx, &function_name,
|
||||||
llonce_fn_ty);
|
llonce_fn_ty);
|
||||||
let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig);
|
let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig);
|
||||||
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
|
|
||||||
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
|
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
|
||||||
block_arena = TypedArena::new();
|
block_arena = TypedArena::new();
|
||||||
fcx = new_fn_ctxt(ccx,
|
fcx = new_fn_ctxt(ccx,
|
||||||
|
|
|
@ -24,6 +24,7 @@ use llvm::{self, ValueRef};
|
||||||
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
|
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
|
||||||
|
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
|
use middle::infer;
|
||||||
use middle::pat_util;
|
use middle::pat_util;
|
||||||
use middle::subst::{self, Substs};
|
use middle::subst::{self, Substs};
|
||||||
use rustc::front::map as hir_map;
|
use rustc::front::map as hir_map;
|
||||||
|
@ -262,6 +263,7 @@ impl<'tcx> TypeMap<'tcx> {
|
||||||
unique_type_id.push_str(" fn(");
|
unique_type_id.push_str(" fn(");
|
||||||
|
|
||||||
let sig = cx.tcx().erase_late_bound_regions(sig);
|
let sig = cx.tcx().erase_late_bound_regions(sig);
|
||||||
|
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
|
||||||
|
|
||||||
for ¶meter_type in &sig.inputs {
|
for ¶meter_type in &sig.inputs {
|
||||||
let parameter_type_id =
|
let parameter_type_id =
|
||||||
|
|
|
@ -35,6 +35,7 @@ use rustc_front::hir;
|
||||||
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
|
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
|
||||||
use trans;
|
use trans;
|
||||||
use trans::{monomorphize, type_of};
|
use trans::{monomorphize, type_of};
|
||||||
|
use middle::infer;
|
||||||
use middle::ty::{self, Ty};
|
use middle::ty::{self, Ty};
|
||||||
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||||
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
|
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
|
||||||
|
@ -418,19 +419,23 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
// Return type -- llvm::DIBuilder wants this at index 0
|
// Return type -- llvm::DIBuilder wants this at index 0
|
||||||
assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
|
assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
|
||||||
let fn_type = cx.tcx().node_id_to_type(fn_ast_id);
|
let fn_type = cx.tcx().node_id_to_type(fn_ast_id);
|
||||||
|
let fn_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &fn_type);
|
||||||
|
|
||||||
let (sig, abi) = match fn_type.sty {
|
let (sig, abi) = match fn_type.sty {
|
||||||
ty::TyBareFn(_, ref barefnty) => {
|
ty::TyBareFn(_, ref barefnty) => {
|
||||||
(cx.tcx().erase_late_bound_regions(&barefnty.sig), barefnty.abi)
|
let sig = cx.tcx().erase_late_bound_regions(&barefnty.sig);
|
||||||
|
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
|
||||||
|
(sig, barefnty.abi)
|
||||||
}
|
}
|
||||||
ty::TyClosure(def_id, ref substs) => {
|
ty::TyClosure(def_id, ref substs) => {
|
||||||
let closure_type = cx.tcx().closure_type(def_id, substs);
|
let closure_type = cx.tcx().closure_type(def_id, substs);
|
||||||
(cx.tcx().erase_late_bound_regions(&closure_type.sig), closure_type.abi)
|
let sig = cx.tcx().erase_late_bound_regions(&closure_type.sig);
|
||||||
|
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
|
||||||
|
(sig, closure_type.abi)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => cx.sess().bug("get_function_metdata: Expected a function type!")
|
_ => cx.sess().bug("get_function_metdata: Expected a function type!")
|
||||||
};
|
};
|
||||||
let sig = monomorphize::apply_param_substs(cx.tcx(), param_substs, &sig);
|
|
||||||
|
|
||||||
let mut signature = Vec::with_capacity(sig.inputs.len() + 1);
|
let mut signature = Vec::with_capacity(sig.inputs.len() + 1);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ use super::namespace::crate_root_namespace;
|
||||||
|
|
||||||
use trans::common::CrateContext;
|
use trans::common::CrateContext;
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
|
use middle::infer;
|
||||||
use middle::subst::{self, Substs};
|
use middle::subst::{self, Substs};
|
||||||
use middle::ty::{self, Ty};
|
use middle::ty::{self, Ty};
|
||||||
|
|
||||||
|
@ -124,6 +125,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
output.push_str("fn(");
|
output.push_str("fn(");
|
||||||
|
|
||||||
let sig = cx.tcx().erase_late_bound_regions(sig);
|
let sig = cx.tcx().erase_late_bound_regions(sig);
|
||||||
|
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
|
||||||
if !sig.inputs.is_empty() {
|
if !sig.inputs.is_empty() {
|
||||||
for ¶meter_type in &sig.inputs {
|
for ¶meter_type in &sig.inputs {
|
||||||
push_debuginfo_type_name(cx, parameter_type, true, output);
|
push_debuginfo_type_name(cx, parameter_type, true, output);
|
||||||
|
|
|
@ -103,9 +103,6 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
|
||||||
fn_type: ty::Ty<'tcx>) -> ValueRef {
|
fn_type: ty::Ty<'tcx>) -> ValueRef {
|
||||||
debug!("declare_rust_fn(name={:?}, fn_type={:?})", name,
|
debug!("declare_rust_fn(name={:?}, fn_type={:?})", name,
|
||||||
fn_type);
|
fn_type);
|
||||||
let fn_type = infer::normalize_associated_type(ccx.tcx(), &fn_type);
|
|
||||||
debug!("declare_rust_fn (after normalised associated types) fn_type={:?}",
|
|
||||||
fn_type);
|
|
||||||
|
|
||||||
let function_type; // placeholder so that the memory ownership works out ok
|
let function_type; // placeholder so that the memory ownership works out ok
|
||||||
let (sig, abi, env) = match fn_type.sty {
|
let (sig, abi, env) = match fn_type.sty {
|
||||||
|
@ -124,14 +121,15 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
|
||||||
_ => ccx.sess().bug("expected closure or fn")
|
_ => ccx.sess().bug("expected closure or fn")
|
||||||
};
|
};
|
||||||
|
|
||||||
let sig = ty::Binder(ccx.tcx().erase_late_bound_regions(sig));
|
let sig = ccx.tcx().erase_late_bound_regions(sig);
|
||||||
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
|
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
|
||||||
let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi);
|
let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi);
|
||||||
debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty));
|
debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty));
|
||||||
|
|
||||||
// it is ok to directly access sig.0.output because we erased all
|
// it is ok to directly access sig.0.output because we erased all
|
||||||
// late-bound-regions above
|
// late-bound-regions above
|
||||||
let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.0.output);
|
let llfn = declare_fn(ccx, name, llvm::CCallConv, llfty, sig.output);
|
||||||
attributes::from_fn_type(ccx, fn_type).apply_llfn(llfn);
|
attributes::from_fn_type(ccx, fn_type).apply_llfn(llfn);
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use intrinsics::{self, Intrinsic};
|
||||||
use libc;
|
use libc;
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
|
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
|
||||||
|
use middle::infer;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
use middle::subst::FnSpace;
|
use middle::subst::FnSpace;
|
||||||
use trans::adt;
|
use trans::adt;
|
||||||
|
@ -170,13 +171,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||||
|
|
||||||
let _icx = push_ctxt("trans_intrinsic_call");
|
let _icx = push_ctxt("trans_intrinsic_call");
|
||||||
|
|
||||||
let (arg_tys, ret_ty) = match callee_ty.sty {
|
let sig = ccx.tcx().erase_late_bound_regions(callee_ty.fn_sig());
|
||||||
ty::TyBareFn(_, ref f) => {
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
(bcx.tcx().erase_late_bound_regions(&f.sig.inputs()),
|
let arg_tys = sig.inputs;
|
||||||
bcx.tcx().erase_late_bound_regions(&f.sig.output()))
|
let ret_ty = sig.output;
|
||||||
}
|
|
||||||
_ => panic!("expected bare_fn in trans_intrinsic_call")
|
|
||||||
};
|
|
||||||
let foreign_item = tcx.map.expect_foreign_item(node);
|
let foreign_item = tcx.map.expect_foreign_item(node);
|
||||||
let name = foreign_item.name.as_str();
|
let name = foreign_item.name.as_str();
|
||||||
|
|
||||||
|
@ -1330,12 +1328,9 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
|
||||||
|
|
||||||
|
|
||||||
let tcx = bcx.tcx();
|
let tcx = bcx.tcx();
|
||||||
let arg_tys = match callee_ty.sty {
|
let sig = tcx.erase_late_bound_regions(callee_ty.fn_sig());
|
||||||
ty::TyBareFn(_, ref f) => {
|
let sig = infer::normalize_associated_type(tcx, &sig);
|
||||||
bcx.tcx().erase_late_bound_regions(&f.sig.inputs())
|
let arg_tys = sig.inputs;
|
||||||
}
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
// every intrinsic takes a SIMD vector as its first argument
|
// every intrinsic takes a SIMD vector as its first argument
|
||||||
require_simd!(arg_tys[0], "input");
|
require_simd!(arg_tys[0], "input");
|
||||||
|
|
|
@ -12,6 +12,7 @@ use arena::TypedArena;
|
||||||
use back::link;
|
use back::link;
|
||||||
use llvm::{ValueRef, get_params};
|
use llvm::{ValueRef, get_params};
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
|
use middle::infer;
|
||||||
use middle::subst::{Subst, Substs};
|
use middle::subst::{Subst, Substs};
|
||||||
use middle::subst::VecPerParamSpace;
|
use middle::subst::VecPerParamSpace;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
|
@ -522,6 +523,7 @@ fn trans_object_shim<'a, 'tcx>(
|
||||||
let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty);
|
let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty);
|
||||||
|
|
||||||
let sig = ccx.tcx().erase_late_bound_regions(&fty.sig);
|
let sig = ccx.tcx().erase_late_bound_regions(&fty.sig);
|
||||||
|
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||||
|
|
||||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||||
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
|
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
use middle::def_id::DefId;
|
use middle::def_id::DefId;
|
||||||
|
use middle::infer;
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
use trans::adt;
|
use trans::adt;
|
||||||
use trans::common::*;
|
use trans::common::*;
|
||||||
|
@ -89,7 +90,7 @@ pub fn untuple_arguments<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
llenvironment_type: Option<Type>,
|
llenvironment_type: Option<Type>,
|
||||||
sig: &ty::Binder<ty::FnSig<'tcx>>,
|
sig: &ty::FnSig<'tcx>,
|
||||||
abi: abi::Abi)
|
abi: abi::Abi)
|
||||||
-> Type
|
-> Type
|
||||||
{
|
{
|
||||||
|
@ -97,16 +98,17 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
sig,
|
sig,
|
||||||
abi);
|
abi);
|
||||||
|
|
||||||
let sig = cx.tcx().erase_late_bound_regions(sig);
|
|
||||||
assert!(!sig.variadic); // rust fns are never variadic
|
assert!(!sig.variadic); // rust fns are never variadic
|
||||||
|
|
||||||
let mut atys: Vec<Type> = Vec::new();
|
let mut atys: Vec<Type> = Vec::new();
|
||||||
|
|
||||||
// First, munge the inputs, if this has the `rust-call` ABI.
|
// First, munge the inputs, if this has the `rust-call` ABI.
|
||||||
let inputs = &if abi == abi::RustCall {
|
let inputs_temp;
|
||||||
untuple_arguments(cx, &sig.inputs)
|
let inputs = if abi == abi::RustCall {
|
||||||
|
inputs_temp = untuple_arguments(cx, &sig.inputs);
|
||||||
|
&inputs_temp
|
||||||
} else {
|
} else {
|
||||||
sig.inputs
|
&sig.inputs
|
||||||
};
|
};
|
||||||
|
|
||||||
// Arg 0: Output pointer.
|
// Arg 0: Output pointer.
|
||||||
|
@ -155,7 +157,9 @@ pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>)
|
||||||
// FIXME(#19925) once fn item types are
|
// FIXME(#19925) once fn item types are
|
||||||
// zero-sized, we'll need to do something here
|
// zero-sized, we'll need to do something here
|
||||||
if f.abi == abi::Rust || f.abi == abi::RustCall {
|
if f.abi == abi::Rust || f.abi == abi::RustCall {
|
||||||
type_of_rust_fn(cx, None, &f.sig, f.abi)
|
let sig = cx.tcx().erase_late_bound_regions(&f.sig);
|
||||||
|
let sig = infer::normalize_associated_type(cx.tcx(), &sig);
|
||||||
|
type_of_rust_fn(cx, None, &sig, f.abi)
|
||||||
} else {
|
} else {
|
||||||
foreign::lltype_for_foreign_fn(cx, fty)
|
foreign::lltype_for_foreign_fn(cx, fty)
|
||||||
}
|
}
|
||||||
|
|
23
src/test/run-pass/issue-23406.rs
Normal file
23
src/test/run-pass/issue-23406.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
trait Inner {
|
||||||
|
type T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Inner for &'a i32 {
|
||||||
|
type T = i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f<'a>(x: &'a i32) -> <&'a i32 as Inner>::T {
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
22
src/test/run-pass/issue-23598.rs
Normal file
22
src/test/run-pass/issue-23598.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
trait Collection where for<'a> &'a Self: IntoIterator {
|
||||||
|
fn my_iter(&self) -> <&Self as IntoIterator>::IntoIter {
|
||||||
|
self.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Collection for [T] { }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = [0usize];
|
||||||
|
let _ = v.my_iter();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue