Make ty_bare_fn carry an optional def-id indicating whether it is the
type of a fn item or a fn pointer, which are now differentiated. Introduce coercion from fn item to fn pointer.
This commit is contained in:
parent
8c8cb997a5
commit
f46099575a
@ -127,7 +127,11 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
|
||||
ast::ExprCast(ref from, _) => {
|
||||
let toty = ty::expr_ty(v.tcx, e);
|
||||
let fromty = ty::expr_ty(v.tcx, &**from);
|
||||
if !ty::type_is_numeric(toty) && !ty::type_is_unsafe_ptr(toty) {
|
||||
let is_legal_cast =
|
||||
ty::type_is_numeric(toty) ||
|
||||
ty::type_is_unsafe_ptr(toty) ||
|
||||
(ty::type_is_bare_fn(toty) && ty::type_is_bare_fn_item(fromty));
|
||||
if !is_legal_cast {
|
||||
span_err!(v.tcx.sess, e.span, E0012,
|
||||
"can not cast to `{}` in a constant expression",
|
||||
ppaux::ty_to_string(v.tcx, toty));
|
||||
|
@ -824,10 +824,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||
None => { }
|
||||
Some(adjustment) => {
|
||||
match *adjustment {
|
||||
ty::AdjustAddEnv(..) => {
|
||||
// Creating a closure consumes the input and stores it
|
||||
// into the resulting rvalue.
|
||||
debug!("walk_adjustment(AutoAddEnv)");
|
||||
ty::AdjustAddEnv(..) |
|
||||
ty::AdjustReifyFnPointer(..) => {
|
||||
// Creating a closure/fn-pointer consumes the
|
||||
// input and stores it into the resulting
|
||||
// rvalue.
|
||||
debug!("walk_adjustment(AutoAddEnv|AdjustReifyFnPointer)");
|
||||
let cmt_unadjusted =
|
||||
return_if_err!(self.mc.cat_expr_unadjusted(expr));
|
||||
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
|
||||
|
@ -486,8 +486,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
b.repr(self.tcx()));
|
||||
|
||||
match a.sty {
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
self.coerce_from_bare_fn(a, f, b)
|
||||
ty::ty_bare_fn(Some(a_def_id), ref f) => {
|
||||
self.coerce_from_fn_item(a, a_def_id, f, b)
|
||||
}
|
||||
_ => {
|
||||
self.subtype(a, b)
|
||||
@ -495,32 +495,46 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to coerce from a bare Rust function (`extern "Rust" fn`) into a closure or a
|
||||
/// `proc`.
|
||||
fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'tcx>)
|
||||
fn coerce_from_fn_item(&self,
|
||||
a: Ty<'tcx>,
|
||||
fn_def_id_a: ast::DefId,
|
||||
fn_ty_a: &ty::BareFnTy<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
/*!
|
||||
* Attempts to coerce from the type of a Rust function item
|
||||
* into a closure or a `proc`.
|
||||
*/
|
||||
|
||||
self.unpack_actual_value(b, |b| {
|
||||
|
||||
debug!("coerce_from_bare_fn(a={}, b={})",
|
||||
a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));
|
||||
a.repr(self.tcx()), b.repr(self.tcx()));
|
||||
|
||||
if fn_ty_a.abi != abi::Rust || fn_ty_a.unsafety != ast::Unsafety::Normal {
|
||||
return self.subtype(a, b);
|
||||
match b.sty {
|
||||
ty::ty_closure(ref f) => {
|
||||
if fn_ty_a.abi != abi::Rust || fn_ty_a.unsafety != ast::Unsafety::Normal {
|
||||
return self.subtype(a, b);
|
||||
}
|
||||
|
||||
let fn_ty_b = (*f).clone();
|
||||
let adj = ty::AdjustAddEnv(fn_def_id_a, fn_ty_b.store);
|
||||
let a_closure = ty::mk_closure(self.tcx(),
|
||||
ty::ClosureTy {
|
||||
sig: fn_ty_a.sig.clone(),
|
||||
.. *fn_ty_b
|
||||
});
|
||||
try!(self.subtype(a_closure, b));
|
||||
Ok(Some(adj))
|
||||
}
|
||||
ty::ty_bare_fn(None, _) => {
|
||||
let a_fn_pointer = ty::mk_bare_fn(self.tcx(), None, (*fn_ty_a).clone());
|
||||
try!(self.subtype(a_fn_pointer, b));
|
||||
Ok(Some(ty::AdjustReifyFnPointer(fn_def_id_a)))
|
||||
}
|
||||
_ => {
|
||||
return self.subtype(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
let fn_ty_b = match b.sty {
|
||||
ty::ty_closure(ref f) => (*f).clone(),
|
||||
_ => return self.subtype(a, b)
|
||||
};
|
||||
|
||||
let adj = ty::AdjustAddEnv(fn_ty_b.store);
|
||||
let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
|
||||
ty::ClosureTy {
|
||||
sig: fn_ty_a.sig.clone(),
|
||||
.. *fn_ty_b
|
||||
});
|
||||
try!(self.subtype(a_closure, b));
|
||||
Ok(Some(adj))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -568,11 +568,12 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
|
||||
}
|
||||
}
|
||||
|
||||
(&ty::ty_bare_fn(ref a_fty), &ty::ty_bare_fn(ref b_fty)) => {
|
||||
this.bare_fn_tys(a_fty, b_fty).and_then(|fty| {
|
||||
Ok(ty::mk_bare_fn(tcx, fty))
|
||||
})
|
||||
}
|
||||
(&ty::ty_bare_fn(a_opt_def_id, ref a_fty), &ty::ty_bare_fn(b_opt_def_id, ref b_fty))
|
||||
if a_opt_def_id == b_opt_def_id =>
|
||||
{
|
||||
let fty = try!(this.bare_fn_tys(a_fty, b_fty));
|
||||
Ok(ty::mk_bare_fn(tcx, a_opt_def_id, fty))
|
||||
}
|
||||
|
||||
(&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
|
||||
this.closure_tys(&**a_fty, &**b_fty).and_then(|fty| {
|
||||
|
@ -441,8 +441,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
|
||||
Some(adjustment) => {
|
||||
match *adjustment {
|
||||
ty::AdjustAddEnv(..) => {
|
||||
debug!("cat_expr(AdjustAddEnv): {}",
|
||||
ty::AdjustAddEnv(..) | ty::AdjustReifyFnPointer(..) => {
|
||||
debug!("cat_expr(AdjustAddEnv|AdjustReifyFnPointer): {}",
|
||||
expr.repr(self.tcx()));
|
||||
// Convert a bare fn to a closure by adding NULL env.
|
||||
// Result is an rvalue.
|
||||
|
@ -293,7 +293,8 @@ pub enum Variance {
|
||||
|
||||
#[deriving(Clone, Show)]
|
||||
pub enum AutoAdjustment<'tcx> {
|
||||
AdjustAddEnv(ty::TraitStore),
|
||||
AdjustAddEnv(ast::DefId, ty::TraitStore),
|
||||
AdjustReifyFnPointer(ast::DefId), // go from a fn-item type to a fn-pointer type
|
||||
AdjustDerefRef(AutoDerefRef<'tcx>)
|
||||
}
|
||||
|
||||
@ -1243,11 +1244,17 @@ pub enum sty<'tcx> {
|
||||
ty_vec(Ty<'tcx>, Option<uint>), // Second field is length.
|
||||
ty_ptr(mt<'tcx>),
|
||||
ty_rptr(Region, mt<'tcx>),
|
||||
ty_bare_fn(BareFnTy<'tcx>),
|
||||
|
||||
// If the def-id is Some(_), then this is the type of a specific
|
||||
// fn item. Otherwise, if None(_), it a fn pointer type.
|
||||
ty_bare_fn(Option<DefId>, BareFnTy<'tcx>),
|
||||
|
||||
ty_closure(Box<ClosureTy<'tcx>>),
|
||||
ty_trait(Box<TyTrait<'tcx>>),
|
||||
ty_struct(DefId, Substs<'tcx>),
|
||||
|
||||
ty_unboxed_closure(DefId, Region, Substs<'tcx>),
|
||||
|
||||
ty_tup(Vec<Ty<'tcx>>),
|
||||
|
||||
ty_param(ParamTy), // type parameter
|
||||
@ -2339,15 +2346,19 @@ pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, fty: ClosureTy<'tcx>) -> Ty<'tcx> {
|
||||
mk_t(cx, ty_closure(box fty))
|
||||
}
|
||||
|
||||
pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>, fty: BareFnTy<'tcx>) -> Ty<'tcx> {
|
||||
mk_t(cx, ty_bare_fn(fty))
|
||||
pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
|
||||
opt_def_id: Option<ast::DefId>,
|
||||
fty: BareFnTy<'tcx>) -> Ty<'tcx> {
|
||||
mk_t(cx, ty_bare_fn(opt_def_id, fty))
|
||||
}
|
||||
|
||||
pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
|
||||
def_id: ast::DefId,
|
||||
input_tys: &[Ty<'tcx>],
|
||||
output: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let input_args = input_tys.iter().map(|ty| *ty).collect();
|
||||
mk_bare_fn(cx,
|
||||
Some(def_id),
|
||||
BareFnTy {
|
||||
unsafety: ast::Unsafety::Normal,
|
||||
abi: abi::Rust,
|
||||
@ -3560,6 +3571,13 @@ pub fn type_is_bare_fn(ty: Ty) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_is_bare_fn_item(ty: Ty) -> bool {
|
||||
match ty.sty {
|
||||
ty_bare_fn(Some(_), _) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_is_fp(ty: Ty) -> bool {
|
||||
match ty.sty {
|
||||
ty_infer(FloatVar(_)) | ty_float(_) => true,
|
||||
@ -3975,9 +3993,9 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
return match adjustment {
|
||||
Some(adjustment) => {
|
||||
match *adjustment {
|
||||
AdjustAddEnv(store) => {
|
||||
AdjustAddEnv(_, store) => {
|
||||
match unadjusted_ty.sty {
|
||||
ty::ty_bare_fn(ref b) => {
|
||||
ty::ty_bare_fn(Some(_), ref b) => {
|
||||
let bounds = ty::ExistentialBounds {
|
||||
region_bound: ReStatic,
|
||||
builtin_bounds: all_builtin_bounds(),
|
||||
@ -3994,7 +4012,21 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
}
|
||||
ref b => {
|
||||
cx.sess.bug(
|
||||
format!("add_env adjustment on non-bare-fn: \
|
||||
format!("add_env adjustment on non-fn-item: \
|
||||
{}",
|
||||
b).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AdjustReifyFnPointer(_) => {
|
||||
match unadjusted_ty.sty {
|
||||
ty::ty_bare_fn(Some(_), ref b) => {
|
||||
ty::mk_bare_fn(cx, None, (*b).clone())
|
||||
}
|
||||
ref b => {
|
||||
cx.sess.bug(
|
||||
format!("AdjustReifyFnPointer adjustment on non-fn-item: \
|
||||
{}",
|
||||
b).as_slice());
|
||||
}
|
||||
@ -4353,7 +4385,8 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
|
||||
ty_vec(_, None) => "slice".to_string(),
|
||||
ty_ptr(_) => "*-ptr".to_string(),
|
||||
ty_rptr(_, _) => "&-ptr".to_string(),
|
||||
ty_bare_fn(_) => "extern fn".to_string(),
|
||||
ty_bare_fn(Some(_), _) => format!("fn item"),
|
||||
ty_bare_fn(None, _) => "fn pointer".to_string(),
|
||||
ty_closure(_) => "fn".to_string(),
|
||||
ty_trait(ref inner) => {
|
||||
format!("trait {}", item_path_str(cx, inner.principal.def_id()))
|
||||
@ -5884,8 +5917,9 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
|
||||
region(state, r);
|
||||
mt(state, m);
|
||||
}
|
||||
ty_bare_fn(ref b) => {
|
||||
ty_bare_fn(opt_def_id, ref b) => {
|
||||
byte!(14);
|
||||
hash!(opt_def_id);
|
||||
hash!(b.unsafety);
|
||||
hash!(b.abi);
|
||||
fn_sig(state, &b.sig);
|
||||
@ -6252,6 +6286,7 @@ impl<'tcx> AutoAdjustment<'tcx> {
|
||||
pub fn is_identity(&self) -> bool {
|
||||
match *self {
|
||||
AdjustAddEnv(..) => false,
|
||||
AdjustReifyFnPointer(..) => false,
|
||||
AdjustDerefRef(ref r) => r.is_identity(),
|
||||
}
|
||||
}
|
||||
@ -6367,8 +6402,11 @@ impl DebruijnIndex {
|
||||
impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
match *self {
|
||||
AdjustAddEnv(ref trait_store) => {
|
||||
format!("AdjustAddEnv({})", trait_store)
|
||||
AdjustAddEnv(def_id, ref trait_store) => {
|
||||
format!("AdjustAddEnv({},{})", def_id.repr(tcx), trait_store)
|
||||
}
|
||||
AdjustReifyFnPointer(def_id) => {
|
||||
format!("AdjustAddEnv({})", def_id.repr(tcx))
|
||||
}
|
||||
AdjustDerefRef(ref data) => {
|
||||
data.repr(tcx)
|
||||
|
@ -538,8 +538,8 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
ty::ty_tup(ref ts) => {
|
||||
ty::ty_tup(ts.fold_with(this))
|
||||
}
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
ty::ty_bare_fn(f.fold_with(this))
|
||||
ty::ty_bare_fn(opt_def_id, ref f) => {
|
||||
ty::ty_bare_fn(opt_def_id, f.fold_with(this))
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
ty::ty_closure(box f.fold_with(this))
|
||||
|
@ -542,6 +542,7 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
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(),
|
||||
did,
|
||||
&[glue::get_drop_glue_type(ccx, t)],
|
||||
ty::mk_nil(ccx.tcx()));
|
||||
get_extern_fn(ccx,
|
||||
|
@ -18,10 +18,9 @@ pub use self::AutorefArg::*;
|
||||
pub use self::CalleeData::*;
|
||||
pub use self::CallArgs::*;
|
||||
|
||||
use arena::TypedArena;
|
||||
use back::{abi,link};
|
||||
use back::abi;
|
||||
use session;
|
||||
use llvm::{ValueRef, get_param};
|
||||
use llvm::{ValueRef};
|
||||
use llvm;
|
||||
use metadata::csearch;
|
||||
use middle::def;
|
||||
|
@ -13,7 +13,6 @@ pub use self::ClosureKind::*;
|
||||
use back::abi;
|
||||
use back::link::mangle_internal_name_by_path_and_seq;
|
||||
use llvm::ValueRef;
|
||||
use middle::def;
|
||||
use middle::mem_categorization::Typer;
|
||||
use trans::adt;
|
||||
use trans::base::*;
|
||||
@ -603,21 +602,10 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
|
||||
pub fn get_wrapper_for_bare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
closure_ty: Ty<'tcx>,
|
||||
def: def::Def,
|
||||
def_id: ast::DefId,
|
||||
fn_ptr: ValueRef,
|
||||
is_local: bool) -> ValueRef {
|
||||
|
||||
let def_id = match def {
|
||||
def::DefFn(did, _) | def::DefStaticMethod(did, _) |
|
||||
def::DefVariant(_, did, _) | def::DefStruct(did) => did,
|
||||
_ => {
|
||||
ccx.sess().bug(format!("get_wrapper_for_bare_fn: \
|
||||
expected a statically resolved fn, got \
|
||||
{}",
|
||||
def).as_slice());
|
||||
}
|
||||
};
|
||||
|
||||
is_local: bool) -> ValueRef
|
||||
{
|
||||
match ccx.closure_bare_wrapper_cache().borrow().get(&fn_ptr) {
|
||||
Some(&llval) => return llval,
|
||||
None => {}
|
||||
@ -697,11 +685,11 @@ pub fn get_wrapper_for_bare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
pub fn make_closure_from_bare_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
closure_ty: Ty<'tcx>,
|
||||
def: def::Def,
|
||||
def_id: ast::DefId,
|
||||
fn_ptr: ValueRef)
|
||||
-> DatumBlock<'blk, 'tcx, Expr> {
|
||||
let scratch = rvalue_scratch_datum(bcx, closure_ty, "__adjust");
|
||||
let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def, fn_ptr, true);
|
||||
let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def_id, fn_ptr, true);
|
||||
fill_fn_pair(bcx, scratch.val, wrapper, C_null(Type::i8p(bcx.ccx())));
|
||||
|
||||
DatumBlock::new(bcx, scratch.to_expr_datum())
|
||||
|
@ -190,16 +190,15 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, e: &ast::Expr)
|
||||
None => { }
|
||||
Some(adj) => {
|
||||
match adj {
|
||||
ty::AdjustAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
|
||||
let def = ty::resolve_expr(cx.tcx(), e);
|
||||
ty::AdjustAddEnv(def_id, ty::RegionTraitStore(ty::ReStatic, _)) => {
|
||||
let wrapper = closure::get_wrapper_for_bare_fn(cx,
|
||||
ety_adjusted,
|
||||
def,
|
||||
def_id,
|
||||
llconst,
|
||||
true);
|
||||
llconst = C_struct(cx, &[wrapper, C_null(Type::i8p(cx))], false)
|
||||
}
|
||||
ty::AdjustAddEnv(store) => {
|
||||
ty::AdjustAddEnv(_, store) => {
|
||||
cx.sess()
|
||||
.span_bug(e.span,
|
||||
format!("unexpected static function: {}",
|
||||
|
@ -54,7 +54,7 @@ use trans::inline;
|
||||
use trans::tvec;
|
||||
use trans::type_of;
|
||||
use middle::ty::{struct_fields, tup_fields};
|
||||
use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe};
|
||||
use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AdjustAddEnv, AutoUnsafe};
|
||||
use middle::ty::{AutoPtr};
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::ty::MethodCall;
|
||||
@ -177,8 +177,9 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
datum.to_string(bcx.ccx()),
|
||||
adjustment.repr(bcx.tcx()));
|
||||
match adjustment {
|
||||
AdjustAddEnv(..) => {
|
||||
datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
|
||||
AdjustAddEnv(def_id, _) => {
|
||||
datum = unpack_datum!(bcx, add_env(bcx, def_id, expr, datum));
|
||||
}
|
||||
}
|
||||
AdjustDerefRef(ref adj) => {
|
||||
let (autoderefs, use_autoref) = match adj.autoref {
|
||||
@ -466,6 +467,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
fn add_env<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
def_id: ast::DefId,
|
||||
expr: &ast::Expr,
|
||||
datum: Datum<'tcx, Expr>)
|
||||
-> DatumBlock<'blk, 'tcx, Expr> {
|
||||
@ -477,8 +479,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
let closure_ty = expr_ty_adjusted(bcx, expr);
|
||||
let fn_ptr = datum.to_llscalarish(bcx);
|
||||
let def = ty::resolve_expr(bcx.tcx(), expr);
|
||||
closure::make_closure_from_bare_fn(bcx, closure_ty, def, fn_ptr)
|
||||
closure::make_closure_from_bare_fn(bcx, closure_ty, def_id, fn_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,6 +289,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
let dtor_ty = ty::mk_ctor_fn(bcx.tcx(),
|
||||
class_did,
|
||||
&[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);
|
||||
|
@ -639,7 +639,8 @@ fn emit_vtable_methods<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m.repr(tcx),
|
||||
substs.repr(tcx));
|
||||
if m.generics.has_type_params(subst::FnSpace) ||
|
||||
ty::type_has_self(ty::mk_bare_fn(tcx, m.fty.clone())) {
|
||||
ty::type_has_self(ty::mk_bare_fn(tcx, None, m.fty.clone()))
|
||||
{
|
||||
debug!("(making impl vtable) method has self or type \
|
||||
params: {}",
|
||||
token::get_name(name));
|
||||
|
@ -954,7 +954,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
||||
tcx.sess.span_err(ast_ty.span,
|
||||
"variadic function must have C calling convention");
|
||||
}
|
||||
ty::mk_bare_fn(tcx, ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl))
|
||||
ty::mk_bare_fn(tcx, None, ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl))
|
||||
}
|
||||
ast::TyClosure(ref f) => {
|
||||
// Use corresponding trait store to figure out default bounds
|
||||
|
@ -113,7 +113,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
self.add_obligations(&pick, &method_bounds_substs, &method_bounds);
|
||||
|
||||
// Create the final `MethodCallee`.
|
||||
let fty = ty::mk_bare_fn(self.tcx(), ty::BareFnTy {
|
||||
let fty = ty::mk_bare_fn(self.tcx(), None, ty::BareFnTy {
|
||||
sig: ty::Binder(method_sig),
|
||||
unsafety: pick.method_ty.fty.unsafety,
|
||||
abi: pick.method_ty.fty.abi.clone(),
|
||||
|
@ -199,7 +199,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
infer::FnCall,
|
||||
&fn_sig).0;
|
||||
let transformed_self_ty = fn_sig.inputs[0];
|
||||
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||
let fty = ty::mk_bare_fn(tcx, None, ty::BareFnTy {
|
||||
sig: ty::Binder(fn_sig),
|
||||
unsafety: bare_fn_ty.unsafety,
|
||||
abi: bare_fn_ty.abi.clone(),
|
||||
|
@ -1132,9 +1132,9 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
}
|
||||
|
||||
// Compute skolemized form of impl and trait method tys.
|
||||
let impl_fty = ty::mk_bare_fn(tcx, impl_m.fty.clone());
|
||||
let impl_fty = ty::mk_bare_fn(tcx, None, impl_m.fty.clone());
|
||||
let impl_fty = impl_fty.subst(tcx, &impl_to_skol_substs);
|
||||
let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
|
||||
let trait_fty = ty::mk_bare_fn(tcx, None, trait_m.fty.clone());
|
||||
let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
|
||||
|
||||
// Check the impl method type IM is a subtype of the trait method
|
||||
@ -1389,6 +1389,8 @@ fn check_cast(fcx: &FnCtxt,
|
||||
}, t_e, None);
|
||||
}
|
||||
|
||||
let t_e_is_bare_fn_item = ty::type_is_bare_fn_item(t_e);
|
||||
|
||||
let t_1_is_scalar = ty::type_is_scalar(t_1);
|
||||
let t_1_is_char = ty::type_is_char(t_1);
|
||||
let t_1_is_bare_fn = ty::type_is_bare_fn(t_1);
|
||||
@ -1396,7 +1398,9 @@ fn check_cast(fcx: &FnCtxt,
|
||||
|
||||
// casts to scalars other than `char` and `bare fn` are trivial
|
||||
let t_1_is_trivial = t_1_is_scalar && !t_1_is_char && !t_1_is_bare_fn;
|
||||
if ty::type_is_c_like_enum(fcx.tcx(), t_e) && t_1_is_trivial {
|
||||
if t_e_is_bare_fn_item && t_1_is_bare_fn {
|
||||
demand::coerce(fcx, e.span, t_1, &*e);
|
||||
} else if ty::type_is_c_like_enum(fcx.tcx(), t_e) && t_1_is_trivial {
|
||||
if t_1_is_float || ty::type_is_unsafe_ptr(t_1) {
|
||||
fcx.type_error_message(span, |actual| {
|
||||
format!("illegal cast; cast through an \
|
||||
@ -1634,7 +1638,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span: Span,
|
||||
adj: &ty::AutoAdjustment<'tcx>) {
|
||||
match *adj {
|
||||
ty::AdjustAddEnv(..) => { }
|
||||
ty::AdjustAddEnv(..) |
|
||||
ty::AdjustReifyFnPointer(..) => {
|
||||
}
|
||||
ty::AdjustDerefRef(ref d_r) => {
|
||||
match d_r.autoref {
|
||||
Some(ref a_r) => {
|
||||
@ -5627,7 +5633,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
|
||||
};
|
||||
(n_tps, inputs, ty::FnConverging(output))
|
||||
};
|
||||
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||
let fty = ty::mk_bare_fn(tcx, None, ty::BareFnTy {
|
||||
unsafety: ast::Unsafety::Unsafe,
|
||||
abi: abi::RustIntrinsic,
|
||||
sig: ty::Binder(FnSig {
|
||||
|
@ -15,7 +15,6 @@ use self::ResolveReason::*;
|
||||
|
||||
use astconv::AstConv;
|
||||
use check::FnCtxt;
|
||||
use middle::def;
|
||||
use middle::pat_util;
|
||||
use middle::ty::{mod, Ty, MethodCall, MethodCallee};
|
||||
use middle::ty_fold::{TypeFolder,TypeFoldable};
|
||||
@ -267,25 +266,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
Some(adjustment) => {
|
||||
let adj_object = ty::adjust_is_object(&adjustment);
|
||||
let resolved_adjustment = match adjustment {
|
||||
ty::AdjustAddEnv(store) => {
|
||||
// FIXME(eddyb) #2190 Allow only statically resolved
|
||||
// bare functions to coerce to a closure to avoid
|
||||
// constructing (slower) indirect call wrappers.
|
||||
match self.tcx().def_map.borrow().get(&id) {
|
||||
Some(&def::DefFn(..)) |
|
||||
Some(&def::DefStaticMethod(..)) |
|
||||
Some(&def::DefVariant(..)) |
|
||||
Some(&def::DefStruct(_)) => {
|
||||
}
|
||||
_ => {
|
||||
span_err!(self.tcx().sess, reason.span(self.tcx()), E0100,
|
||||
"cannot coerce non-statically resolved bare fn to closure");
|
||||
span_help!(self.tcx().sess, reason.span(self.tcx()),
|
||||
"consider embedding the function in a closure");
|
||||
}
|
||||
}
|
||||
ty::AdjustAddEnv(def_id, store) => {
|
||||
ty::AdjustAddEnv(def_id, self.resolve(&store, reason))
|
||||
}
|
||||
|
||||
ty::AdjustAddEnv(self.resolve(&store, reason))
|
||||
ty::AdjustReifyFnPointer(def_id) => {
|
||||
ty::AdjustReifyFnPointer(def_id)
|
||||
}
|
||||
|
||||
ty::AdjustDerefRef(adj) => {
|
||||
|
@ -235,7 +235,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
// impl, plus its own.
|
||||
let new_polytype = ty::Polytype {
|
||||
generics: new_method_ty.generics.clone(),
|
||||
ty: ty::mk_bare_fn(tcx, new_method_ty.fty.clone())
|
||||
ty: ty::mk_bare_fn(tcx, Some(new_did), new_method_ty.fty.clone())
|
||||
};
|
||||
debug!("new_polytype={}", new_polytype.repr(tcx));
|
||||
|
||||
|
@ -211,13 +211,15 @@ pub fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
// Create a set of parameter types shared among all the variants.
|
||||
for variant in variants.iter() {
|
||||
let variant_def_id = local_def(variant.node.id);
|
||||
|
||||
// Nullary enum constructors get turned into constants; n-ary enum
|
||||
// constructors get turned into functions.
|
||||
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, input_tys.as_slice(), enum_ty)
|
||||
ty::mk_ctor_fn(tcx, variant_def_id, input_tys.as_slice(), enum_ty)
|
||||
}
|
||||
|
||||
ast::TupleVariantKind(_) => {
|
||||
@ -246,7 +248,7 @@ pub fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
ty: result_ty
|
||||
};
|
||||
|
||||
tcx.tcache.borrow_mut().insert(local_def(variant.node.id), pty);
|
||||
tcx.tcache.borrow_mut().insert(variant_def_id, pty);
|
||||
|
||||
write_ty_to_tcx(tcx, variant.node.id, result_ty);
|
||||
}
|
||||
@ -353,7 +355,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
m.def_id,
|
||||
Polytype {
|
||||
generics: m.generics.clone(),
|
||||
ty: ty::mk_bare_fn(ccx.tcx, m.fty.clone()) });
|
||||
ty: ty::mk_bare_fn(ccx.tcx, Some(m.def_id), m.fty.clone()) });
|
||||
}
|
||||
|
||||
fn ty_method_of_trait_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
@ -519,6 +521,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
tcx.sess.span_err(m.span, "duplicate method in trait impl");
|
||||
}
|
||||
|
||||
let m_def_id = local_def(m.id);
|
||||
let mty = Rc::new(ty_of_method(ccx,
|
||||
convert_method_context,
|
||||
container,
|
||||
@ -526,13 +529,13 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
untransformed_rcvr_ty,
|
||||
rcvr_ty_generics,
|
||||
rcvr_visibility));
|
||||
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
|
||||
let fty = ty::mk_bare_fn(tcx, Some(m_def_id), mty.fty.clone());
|
||||
debug!("method {} (id {}) has type {}",
|
||||
m.pe_ident().repr(tcx),
|
||||
m.id,
|
||||
fty.repr(tcx));
|
||||
tcx.tcache.borrow_mut().insert(
|
||||
local_def(m.id),
|
||||
m_def_id,
|
||||
Polytype {
|
||||
generics: mty.generics.clone(),
|
||||
ty: fty
|
||||
@ -1279,6 +1282,7 @@ pub fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|field| (*tcx.tcache.borrow())[
|
||||
local_def(field.node.id)].ty).collect();
|
||||
let ctor_fn_ty = ty::mk_ctor_fn(tcx,
|
||||
local_def(ctor_id),
|
||||
inputs.as_slice(),
|
||||
selfty);
|
||||
write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
|
||||
@ -1461,7 +1465,7 @@ pub fn ty_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
|
||||
};
|
||||
let pty = Polytype {
|
||||
generics: ty_generics,
|
||||
ty: ty::mk_bare_fn(ccx.tcx, tofd)
|
||||
ty: ty::mk_bare_fn(ccx.tcx, Some(local_def(it.id)), tofd)
|
||||
};
|
||||
debug!("type of {} (id {}) is {}",
|
||||
token::get_ident(it.ident),
|
||||
@ -2138,6 +2142,7 @@ pub fn ty_of_foreign_fn_decl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
let t_fn = ty::mk_bare_fn(
|
||||
ccx.tcx,
|
||||
None,
|
||||
ty::BareFnTy {
|
||||
abi: abi,
|
||||
unsafety: ast::Unsafety::Unsafe,
|
||||
|
@ -102,6 +102,7 @@ use util::ppaux;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::print::pprust::*;
|
||||
use syntax::{ast, ast_map, abi};
|
||||
use syntax::ast_util::local_def;
|
||||
|
||||
#[cfg(stage0)]
|
||||
mod diagnostics;
|
||||
@ -224,7 +225,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||
let se_ty = ty::mk_bare_fn(tcx, Some(local_def(main_id)), ty::BareFnTy {
|
||||
unsafety: ast::Unsafety::Normal,
|
||||
abi: abi::Rust,
|
||||
sig: ty::Binder(ty::FnSig {
|
||||
@ -272,7 +273,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
||||
_ => ()
|
||||
}
|
||||
|
||||
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||
let se_ty = ty::mk_bare_fn(tcx, Some(local_def(start_id)), ty::BareFnTy {
|
||||
unsafety: ast::Unsafety::Normal,
|
||||
abi: abi::Rust,
|
||||
sig: ty::Binder(ty::FnSig {
|
||||
|
Loading…
x
Reference in New Issue
Block a user