mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
rustc: combine BareFnTy and ClosureTy into FnSig.
This commit is contained in:
parent
28f1cf4262
commit
91374f8fe4
@ -600,7 +600,7 @@ impl_trans_normalize!('gcx,
|
||||
Ty<'gcx>,
|
||||
&'gcx Substs<'gcx>,
|
||||
ty::FnSig<'gcx>,
|
||||
&'gcx ty::BareFnTy<'gcx>,
|
||||
ty::PolyFnSig<'gcx>,
|
||||
ty::ClosureSubsts<'gcx>,
|
||||
ty::PolyTraitRef<'gcx>,
|
||||
ty::ExistentialTraitRef<'gcx>
|
||||
@ -1652,7 +1652,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn closure_type(&self,
|
||||
def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
-> ty::PolyFnSig<'tcx>
|
||||
{
|
||||
if let InferTables::InProgress(tables) = self.tables {
|
||||
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
|
||||
|
@ -44,8 +44,8 @@ enum RootUnsafeContext {
|
||||
|
||||
fn type_is_unsafe_function(ty: Ty) -> bool {
|
||||
match ty.sty {
|
||||
ty::TyFnDef(.., ref f) |
|
||||
ty::TyFnPtr(ref f) => f.unsafety == hir::Unsafety::Unsafe,
|
||||
ty::TyFnDef(.., f) |
|
||||
ty::TyFnPtr(f) => f.unsafety() == hir::Unsafety::Unsafe,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ struct ExprVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
|
||||
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
|
||||
let intrinsic = match self.infcx.tcx.item_type(def_id).sty {
|
||||
ty::TyFnDef(.., ref bfty) => bfty.abi == RustIntrinsic,
|
||||
ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic,
|
||||
_ => return false
|
||||
};
|
||||
intrinsic && self.infcx.tcx.item_name(def_id) == "transmute"
|
||||
@ -137,9 +137,9 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> {
|
||||
let typ = self.infcx.tables.borrow().node_id_to_type(expr.id);
|
||||
let typ = self.infcx.tcx.lift_to_global(&typ).unwrap();
|
||||
match typ.sty {
|
||||
ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
|
||||
let from = bare_fn_ty.sig.skip_binder().inputs()[0];
|
||||
let to = bare_fn_ty.sig.skip_binder().output();
|
||||
ty::TyFnDef(.., sig) if sig.abi() == RustIntrinsic => {
|
||||
let from = sig.inputs().skip_binder()[0];
|
||||
let to = *sig.output().skip_binder();
|
||||
self.check_transmute(expr.span, from, to, expr.id);
|
||||
}
|
||||
_ => {
|
||||
|
@ -1434,7 +1434,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
let fn_ty = self.ir.tcx.item_type(self.ir.tcx.hir.local_def_id(id));
|
||||
let fn_ret = match fn_ty.sty {
|
||||
ty::TyClosure(closure_def_id, substs) =>
|
||||
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
|
||||
self.ir.tcx.closure_type(closure_def_id, substs).output(),
|
||||
_ => fn_ty.fn_ret()
|
||||
};
|
||||
|
||||
|
@ -1224,7 +1224,7 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
|
||||
|
||||
confirm_callable_candidate(selcx,
|
||||
obligation,
|
||||
&closure_type.sig,
|
||||
closure_type,
|
||||
util::TupleArgumentsFlag::No)
|
||||
.with_addl_obligations(vtable.nested)
|
||||
.with_addl_obligations(obligations)
|
||||
@ -1233,7 +1233,7 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
|
||||
fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
fn_sig: &ty::PolyFnSig<'tcx>,
|
||||
fn_sig: ty::PolyFnSig<'tcx>,
|
||||
flag: util::TupleArgumentsFlag)
|
||||
-> Progress<'tcx>
|
||||
{
|
||||
|
@ -1405,16 +1405,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
// provide an impl, but only for suitable `fn` pointers
|
||||
ty::TyFnDef(.., &ty::BareFnTy {
|
||||
ty::TyFnDef(.., ty::Binder(ty::FnSig {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
ref sig,
|
||||
}) |
|
||||
ty::TyFnPtr(&ty::BareFnTy {
|
||||
variadic: false,
|
||||
..
|
||||
})) |
|
||||
ty::TyFnPtr(ty::Binder(ty::FnSig {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
ref sig
|
||||
}) if !sig.variadic() => {
|
||||
variadic: false,
|
||||
..
|
||||
})) => {
|
||||
candidates.vec.push(FnPointerCandidate);
|
||||
}
|
||||
|
||||
@ -2781,7 +2783,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
let ty::Binder((trait_ref, _)) =
|
||||
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
||||
obligation.predicate.0.self_ty(), // (1)
|
||||
&closure_type.sig,
|
||||
closure_type,
|
||||
util::TupleArgumentsFlag::No);
|
||||
// (1) Feels icky to skip the binder here, but OTOH we know
|
||||
// that the self-type is an unboxed closure type and hence is
|
||||
|
@ -482,7 +482,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn closure_trait_ref_and_return_type(self,
|
||||
fn_trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
sig: &ty::PolyFnSig<'tcx>,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
tuple_arguments: TupleArgumentsFlag)
|
||||
-> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)>
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ use ty::{self, TraitRef, Ty, TypeAndMut};
|
||||
use ty::{TyS, TypeVariants, Slice};
|
||||
use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
|
||||
use hir::FreevarMap;
|
||||
use ty::{BareFnTy, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
|
||||
use ty::TypeVariants::*;
|
||||
use ty::layout::{Layout, TargetDataLayout};
|
||||
@ -53,6 +53,7 @@ use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::iter;
|
||||
use std::cmp::Ordering;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::attr;
|
||||
use syntax::symbol::{Symbol, keywords};
|
||||
@ -94,7 +95,6 @@ pub struct CtxtInterners<'tcx> {
|
||||
type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
|
||||
type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
|
||||
substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
|
||||
bare_fn: RefCell<FxHashSet<Interned<'tcx, BareFnTy<'tcx>>>>,
|
||||
region: RefCell<FxHashSet<Interned<'tcx, Region>>>,
|
||||
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
|
||||
}
|
||||
@ -106,7 +106,6 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
|
||||
type_: RefCell::new(FxHashSet()),
|
||||
type_list: RefCell::new(FxHashSet()),
|
||||
substs: RefCell::new(FxHashSet()),
|
||||
bare_fn: RefCell::new(FxHashSet()),
|
||||
region: RefCell::new(FxHashSet()),
|
||||
existential_predicates: RefCell::new(FxHashSet()),
|
||||
}
|
||||
@ -219,7 +218,7 @@ pub struct TypeckTables<'tcx> {
|
||||
pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
|
||||
|
||||
/// Records the type of each closure.
|
||||
pub closure_tys: NodeMap<ty::ClosureTy<'tcx>>,
|
||||
pub closure_tys: NodeMap<ty::PolyFnSig<'tcx>>,
|
||||
|
||||
/// Records the kind of each closure.
|
||||
pub closure_kinds: NodeMap<ty::ClosureKind>,
|
||||
@ -859,23 +858,6 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<ExistentialPredicate<'a>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for &'a BareFnTy<'a> {
|
||||
type Lifted = &'tcx BareFnTy<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
|
||||
-> Option<&'tcx BareFnTy<'tcx>> {
|
||||
if tcx.interners.arena.in_arena(*self as *const _) {
|
||||
return Some(unsafe { mem::transmute(*self) });
|
||||
}
|
||||
// Also try in the global tcx if we're not that.
|
||||
if !tcx.is_global() {
|
||||
self.lift_to_tcx(tcx.global_tcx())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub mod tls {
|
||||
use super::{CtxtInterners, GlobalCtxt, TyCtxt};
|
||||
|
||||
@ -1028,7 +1010,6 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
TyDynamic, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon);
|
||||
|
||||
println!("Substs interner: #{}", self.interners.substs.borrow().len());
|
||||
println!("BareFnTy interner: #{}", self.interners.bare_fn.borrow().len());
|
||||
println!("Region interner: #{}", self.interners.region.borrow().len());
|
||||
println!("Stability interner: #{}", self.stability_interner.borrow().len());
|
||||
println!("Layout interner: #{}", self.layout_interner.borrow().len());
|
||||
@ -1087,12 +1068,6 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, Substs<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx: 'lcx, 'lcx> Borrow<BareFnTy<'lcx>> for Interned<'tcx, BareFnTy<'tcx>> {
|
||||
fn borrow<'a>(&'a self) -> &'a BareFnTy<'lcx> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Borrow<Region> for Interned<'tcx, Region> {
|
||||
fn borrow<'a>(&'a self) -> &'a Region {
|
||||
self.0
|
||||
@ -1181,9 +1156,6 @@ fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
|
||||
}
|
||||
|
||||
direct_interners!('tcx,
|
||||
bare_fn: mk_bare_fn(|fty: &BareFnTy| {
|
||||
keep_local(&fty.sig)
|
||||
}) -> BareFnTy<'tcx>,
|
||||
region: mk_region(|r| {
|
||||
match r {
|
||||
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
|
||||
@ -1209,12 +1181,11 @@ slice_interners!(
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// Create an unsafe fn ty based on a safe fn ty.
|
||||
pub fn safe_to_unsafe_fn_ty(self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
|
||||
assert_eq!(bare_fn.unsafety, hir::Unsafety::Normal);
|
||||
self.mk_fn_ptr(self.mk_bare_fn(ty::BareFnTy {
|
||||
pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
assert_eq!(sig.unsafety(), hir::Unsafety::Normal);
|
||||
self.mk_fn_ptr(sig.map_bound(|sig| ty::FnSig {
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
abi: bare_fn.abi,
|
||||
sig: bare_fn.sig.clone()
|
||||
..sig
|
||||
}))
|
||||
}
|
||||
|
||||
@ -1341,11 +1312,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
pub fn mk_fn_def(self, def_id: DefId,
|
||||
substs: &'tcx Substs<'tcx>,
|
||||
fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
|
||||
fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
self.mk_ty(TyFnDef(def_id, substs, fty))
|
||||
}
|
||||
|
||||
pub fn mk_fn_ptr(self, fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
|
||||
pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
self.mk_ty(TyFnPtr(fty))
|
||||
}
|
||||
|
||||
@ -1439,14 +1410,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mk_fn_sig<I>(self, inputs: I, output: I::Item, variadic: bool)
|
||||
pub fn mk_fn_sig<I>(self,
|
||||
inputs: I,
|
||||
output: I::Item,
|
||||
variadic: bool,
|
||||
unsafety: hir::Unsafety,
|
||||
abi: abi::Abi)
|
||||
-> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
|
||||
where I: Iterator,
|
||||
I::Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>
|
||||
{
|
||||
inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
|
||||
inputs_and_output: self.intern_type_list(xs),
|
||||
variadic: variadic
|
||||
variadic, unsafety, abi
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
Some(TupleSimplifiedType(tys.len()))
|
||||
}
|
||||
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {
|
||||
Some(FunctionSimplifiedType(f.sig.skip_binder().inputs().len()))
|
||||
Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
|
||||
}
|
||||
ty::TyProjection(_) | ty::TyParam(_) => {
|
||||
if can_simplify_params {
|
||||
|
@ -155,13 +155,13 @@ impl FlagComputation {
|
||||
self.add_tys(&ts[..]);
|
||||
}
|
||||
|
||||
&ty::TyFnDef(_, substs, ref f) => {
|
||||
&ty::TyFnDef(_, substs, f) => {
|
||||
self.add_substs(substs);
|
||||
self.add_fn_sig(&f.sig);
|
||||
self.add_fn_sig(f);
|
||||
}
|
||||
|
||||
&ty::TyFnPtr(ref f) => {
|
||||
self.add_fn_sig(&f.sig);
|
||||
&ty::TyFnPtr(f) => {
|
||||
self.add_fn_sig(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,7 +177,7 @@ impl FlagComputation {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_fn_sig(&mut self, fn_sig: &ty::PolyFnSig) {
|
||||
fn add_fn_sig(&mut self, fn_sig: ty::PolyFnSig) {
|
||||
let mut computation = FlagComputation::new();
|
||||
|
||||
computation.add_tys(fn_sig.skip_binder().inputs());
|
||||
|
@ -159,19 +159,6 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized {
|
||||
sig.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_bare_fn_ty(&mut self,
|
||||
fty: &'tcx ty::BareFnTy<'tcx>)
|
||||
-> &'tcx ty::BareFnTy<'tcx>
|
||||
{
|
||||
fty.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_closure_ty(&mut self,
|
||||
fty: &ty::ClosureTy<'tcx>)
|
||||
-> ty::ClosureTy<'tcx> {
|
||||
fty.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
||||
r.super_fold_with(self)
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ define_maps! { <'tcx>
|
||||
|
||||
/// Records the type of each closure. The def ID is the ID of the
|
||||
/// expression defining the closure.
|
||||
pub closure_type: ItemSignature(DefId) -> ty::ClosureTy<'tcx>,
|
||||
pub closure_type: ItemSignature(DefId) -> ty::PolyFnSig<'tcx>,
|
||||
|
||||
/// Caches CoerceUnsized kinds for impls on custom types.
|
||||
pub custom_coerce_unsized_kind: ItemSignature(DefId)
|
||||
|
@ -55,8 +55,8 @@ use hir;
|
||||
use hir::itemlikevisit::ItemLikeVisitor;
|
||||
|
||||
pub use self::sty::{Binder, DebruijnIndex};
|
||||
pub use self::sty::{BareFnTy, FnSig, PolyFnSig};
|
||||
pub use self::sty::{ClosureTy, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||
pub use self::sty::{FnSig, PolyFnSig};
|
||||
pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||
pub use self::sty::{ClosureSubsts, TypeAndMut};
|
||||
pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
|
||||
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
|
||||
@ -2470,7 +2470,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn closure_type(self,
|
||||
def_id: DefId,
|
||||
substs: ClosureSubsts<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
-> ty::PolyFnSig<'tcx>
|
||||
{
|
||||
if let Some(ty) = self.maps.closure_type.borrow().get(&def_id) {
|
||||
return ty.subst(self, substs.substs);
|
||||
|
@ -157,24 +157,6 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
||||
Ok(tcx.mk_substs(params)?)
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for &'tcx ty::BareFnTy<'tcx> {
|
||||
fn relate<'a, 'gcx, R>(relation: &mut R,
|
||||
a: &&'tcx ty::BareFnTy<'tcx>,
|
||||
b: &&'tcx ty::BareFnTy<'tcx>)
|
||||
-> RelateResult<'tcx, &'tcx ty::BareFnTy<'tcx>>
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||
{
|
||||
let unsafety = relation.relate(&a.unsafety, &b.unsafety)?;
|
||||
let abi = relation.relate(&a.abi, &b.abi)?;
|
||||
let sig = relation.relate(&a.sig, &b.sig)?;
|
||||
Ok(relation.tcx().mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
sig: sig
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
|
||||
fn relate<'a, 'gcx, R>(relation: &mut R,
|
||||
a: &ty::FnSig<'tcx>,
|
||||
@ -186,6 +168,8 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
|
||||
return Err(TypeError::VariadicMismatch(
|
||||
expected_found(relation, &a.variadic, &b.variadic)));
|
||||
}
|
||||
let unsafety = relation.relate(&a.unsafety, &b.unsafety)?;
|
||||
let abi = relation.relate(&a.abi, &b.abi)?;
|
||||
|
||||
if a.inputs().len() != b.inputs().len() {
|
||||
return Err(TypeError::ArgCount);
|
||||
@ -204,7 +188,9 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
|
||||
}).collect::<Result<AccumulateVec<[_; 8]>, _>>()?;
|
||||
Ok(ty::FnSig {
|
||||
inputs_and_output: relation.tcx().intern_type_list(&inputs_and_output),
|
||||
variadic: a.variadic
|
||||
variadic: a.variadic,
|
||||
unsafety: unsafety,
|
||||
abi: abi
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -235,20 +235,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
|
||||
tcx.lift(&self.inputs_and_output).map(|x| {
|
||||
ty::FnSig {
|
||||
inputs_and_output: x,
|
||||
variadic: self.variadic
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::ClosureTy<'a> {
|
||||
type Lifted = ty::ClosureTy<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(&self.sig).map(|sig| {
|
||||
ty::ClosureTy {
|
||||
sig: sig,
|
||||
variadic: self.variadic,
|
||||
unsafety: self.unsafety,
|
||||
abi: self.abi
|
||||
abi: self.abi,
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -531,43 +520,6 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::BareFnTy<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
let fty = ty::BareFnTy {
|
||||
sig: self.sig.fold_with(folder),
|
||||
abi: self.abi,
|
||||
unsafety: self.unsafety
|
||||
};
|
||||
folder.tcx().mk_bare_fn(fty)
|
||||
}
|
||||
|
||||
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
folder.fold_bare_fn_ty(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.sig.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureTy<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ty::ClosureTy {
|
||||
sig: self.sig.fold_with(folder),
|
||||
unsafety: self.unsafety,
|
||||
abi: self.abi,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
folder.fold_closure_ty(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.sig.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl }
|
||||
@ -588,6 +540,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
|
||||
ty::FnSig {
|
||||
inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
|
||||
variadic: self.variadic,
|
||||
unsafety: self.unsafety,
|
||||
abi: self.abi,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,12 +128,12 @@ pub enum TypeVariants<'tcx> {
|
||||
|
||||
/// The anonymous type of a function declaration/definition. Each
|
||||
/// function has a unique type.
|
||||
TyFnDef(DefId, &'tcx Substs<'tcx>, &'tcx BareFnTy<'tcx>),
|
||||
TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>),
|
||||
|
||||
/// A pointer to a function. Written as `fn() -> i32`.
|
||||
/// FIXME: This is currently also used to represent the callee of a method;
|
||||
/// see ty::MethodCallee etc.
|
||||
TyFnPtr(&'tcx BareFnTy<'tcx>),
|
||||
TyFnPtr(PolyFnSig<'tcx>),
|
||||
|
||||
/// A trait, defined with `trait`.
|
||||
TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, &'tcx ty::Region),
|
||||
@ -531,38 +531,22 @@ pub struct ProjectionTy<'tcx> {
|
||||
/// The name `N` of the associated type.
|
||||
pub item_name: Name,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct BareFnTy<'tcx> {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub abi: abi::Abi,
|
||||
/// Signature (inputs and output) of this function type.
|
||||
pub sig: PolyFnSig<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx BareFnTy<'tcx> {}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct ClosureTy<'tcx> {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub abi: abi::Abi,
|
||||
pub sig: PolyFnSig<'tcx>,
|
||||
}
|
||||
|
||||
/// Signature of a function type, which I have arbitrarily
|
||||
/// decided to use to refer to the input/output types.
|
||||
///
|
||||
/// - `inputs` is the list of arguments and their modes.
|
||||
/// - `output` is the return type.
|
||||
/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
|
||||
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct FnSig<'tcx> {
|
||||
pub inputs_and_output: &'tcx Slice<Ty<'tcx>>,
|
||||
pub variadic: bool
|
||||
pub variadic: bool,
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub abi: abi::Abi,
|
||||
}
|
||||
|
||||
impl<'tcx> FnSig<'tcx> {
|
||||
pub fn inputs(&self) -> &[Ty<'tcx>] {
|
||||
pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
|
||||
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
|
||||
}
|
||||
|
||||
@ -574,7 +558,7 @@ impl<'tcx> FnSig<'tcx> {
|
||||
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyFnSig<'tcx> {
|
||||
pub fn inputs(&self) -> Binder<&[Ty<'tcx>]> {
|
||||
pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
|
||||
Binder(self.skip_binder().inputs())
|
||||
}
|
||||
pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
|
||||
@ -586,6 +570,12 @@ impl<'tcx> PolyFnSig<'tcx> {
|
||||
pub fn variadic(&self) -> bool {
|
||||
self.skip_binder().variadic
|
||||
}
|
||||
pub fn unsafety(&self) -> hir::Unsafety {
|
||||
self.skip_binder().unsafety
|
||||
}
|
||||
pub fn abi(&self) -> abi::Abi {
|
||||
self.skip_binder().abi
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
@ -1280,23 +1270,15 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_sig(&self) -> &'tcx PolyFnSig<'tcx> {
|
||||
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
||||
match self.sty {
|
||||
TyFnDef(.., ref f) | TyFnPtr(ref f) => &f.sig,
|
||||
TyFnDef(.., f) | TyFnPtr(f) => f,
|
||||
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the ABI of the given function.
|
||||
pub fn fn_abi(&self) -> abi::Abi {
|
||||
match self.sty {
|
||||
TyFnDef(.., ref f) | TyFnPtr(ref f) => f.abi,
|
||||
_ => bug!("Ty::fn_abi() called on non-fn type"),
|
||||
}
|
||||
}
|
||||
|
||||
// Type accessors for substructures of types
|
||||
pub fn fn_args(&self) -> ty::Binder<&[Ty<'tcx>]> {
|
||||
pub fn fn_args(&self) -> ty::Binder<&'tcx [Ty<'tcx>]> {
|
||||
self.fn_sig().inputs()
|
||||
}
|
||||
|
||||
|
@ -456,10 +456,10 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
|
||||
TyFnDef(def_id, ..) => self.def_id(def_id),
|
||||
TyAdt(d, _) => self.def_id(d.did),
|
||||
TyFnPtr(f) => {
|
||||
self.hash(f.unsafety);
|
||||
self.hash(f.abi);
|
||||
self.hash(f.sig.variadic());
|
||||
self.hash(f.sig.skip_binder().inputs().len());
|
||||
self.hash(f.unsafety());
|
||||
self.hash(f.abi());
|
||||
self.hash(f.variadic());
|
||||
self.hash(f.inputs().skip_binder().len());
|
||||
}
|
||||
TyDynamic(ref data, ..) => {
|
||||
if let Some(p) = data.principal() {
|
||||
|
@ -115,17 +115,17 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
||||
ty::TyTuple(ts, _) => {
|
||||
stack.extend(ts.iter().cloned().rev());
|
||||
}
|
||||
ty::TyFnDef(_, substs, ref ft) => {
|
||||
ty::TyFnDef(_, substs, ft) => {
|
||||
stack.extend(substs.types().rev());
|
||||
push_sig_subtypes(stack, &ft.sig);
|
||||
push_sig_subtypes(stack, ft);
|
||||
}
|
||||
ty::TyFnPtr(ref ft) => {
|
||||
push_sig_subtypes(stack, &ft.sig);
|
||||
ty::TyFnPtr(ft) => {
|
||||
push_sig_subtypes(stack, ft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) {
|
||||
fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: ty::PolyFnSig<'tcx>) {
|
||||
stack.push(sig.skip_binder().output());
|
||||
stack.extend(sig.skip_binder().inputs().iter().cloned().rev());
|
||||
}
|
||||
|
@ -495,15 +495,6 @@ impl fmt::Debug for ty::Region {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ClosureTy({},{:?},{})",
|
||||
self.unsafety,
|
||||
self.sig,
|
||||
self.abi)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ClosureUpvar({:?},{:?})",
|
||||
@ -585,6 +576,14 @@ impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
|
||||
|
||||
impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.unsafety == hir::Unsafety::Unsafe {
|
||||
write!(f, "unsafe ")?;
|
||||
}
|
||||
|
||||
if self.abi != Abi::Rust {
|
||||
write!(f, "extern {} ", self.abi)?;
|
||||
}
|
||||
|
||||
write!(f, "fn")?;
|
||||
fn_sig(f, self.inputs(), self.variadic, self.output())
|
||||
}
|
||||
@ -741,28 +740,12 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
||||
write!(f, ")")
|
||||
}
|
||||
TyFnDef(def_id, substs, ref bare_fn) => {
|
||||
if bare_fn.unsafety == hir::Unsafety::Unsafe {
|
||||
write!(f, "unsafe ")?;
|
||||
}
|
||||
|
||||
if bare_fn.abi != Abi::Rust {
|
||||
write!(f, "extern {} ", bare_fn.abi)?;
|
||||
}
|
||||
|
||||
write!(f, "{} {{", bare_fn.sig.0)?;
|
||||
write!(f, "{} {{", bare_fn.0)?;
|
||||
parameterized(f, substs, def_id, &[])?;
|
||||
write!(f, "}}")
|
||||
}
|
||||
TyFnPtr(ref bare_fn) => {
|
||||
if bare_fn.unsafety == hir::Unsafety::Unsafe {
|
||||
write!(f, "unsafe ")?;
|
||||
}
|
||||
|
||||
if bare_fn.abi != Abi::Rust {
|
||||
write!(f, "extern {} ", bare_fn.abi)?;
|
||||
}
|
||||
|
||||
write!(f, "{}", bare_fn.sig.0)
|
||||
write!(f, "{}", bare_fn.0)
|
||||
}
|
||||
TyInfer(infer_ty) => write!(f, "{}", infer_ty),
|
||||
TyError => write!(f, "[type error]"),
|
||||
|
@ -164,8 +164,9 @@ fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
{
|
||||
if let mir::Operand::Constant(ref func) = *oper
|
||||
{
|
||||
if let ty::TyFnDef(def_id, _, &ty::BareFnTy { abi, .. }) = func.ty.sty
|
||||
if let ty::TyFnDef(def_id, _, sig) = func.ty.sty
|
||||
{
|
||||
let abi = sig.abi();
|
||||
let name = tcx.item_name(def_id);
|
||||
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
|
||||
if name == "rustc_peek" {
|
||||
|
@ -270,11 +270,13 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn t_fn(&self, input_tys: &[Ty<'tcx>], output_ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.infcx.tcx.mk_fn_ptr(self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
sig: ty::Binder(self.infcx.tcx.mk_fn_sig(input_tys.iter().cloned(), output_ty, false)),
|
||||
}))
|
||||
self.infcx.tcx.mk_fn_ptr(ty::Binder(self.infcx.tcx.mk_fn_sig(
|
||||
input_tys.iter().cloned(),
|
||||
output_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn t_nil(&self) -> Ty<'tcx> {
|
||||
|
@ -1082,9 +1082,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
|
||||
}
|
||||
let typ = cx.tables.node_id_to_type(expr.id);
|
||||
match typ.sty {
|
||||
ty::TyFnDef(.., ref bare_fn) if bare_fn.abi == RustIntrinsic => {
|
||||
let from = bare_fn.sig.skip_binder().inputs()[0];
|
||||
let to = bare_fn.sig.skip_binder().output();
|
||||
ty::TyFnDef(.., bare_fn) if bare_fn.abi() == RustIntrinsic => {
|
||||
let from = bare_fn.inputs().skip_binder()[0];
|
||||
let to = *bare_fn.output().skip_binder();
|
||||
return Some((&from.sty, &to.sty));
|
||||
}
|
||||
_ => (),
|
||||
@ -1095,7 +1095,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
|
||||
|
||||
fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool {
|
||||
match cx.tcx.item_type(def_id).sty {
|
||||
ty::TyFnDef(.., ref bfty) if bfty.abi == RustIntrinsic => (),
|
||||
ty::TyFnDef(.., bfty) if bfty.abi() == RustIntrinsic => (),
|
||||
_ => return false,
|
||||
}
|
||||
cx.tcx.item_name(def_id) == "transmute"
|
||||
|
@ -568,8 +568,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
|
||||
ty::TyArray(ty, _) => self.check_type_for_ffi(cache, ty),
|
||||
|
||||
ty::TyFnPtr(bare_fn) => {
|
||||
match bare_fn.abi {
|
||||
ty::TyFnPtr(sig) => {
|
||||
match sig.abi() {
|
||||
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
|
||||
return FfiUnsafe("found function pointer with Rust calling convention in \
|
||||
foreign module; consider using an `extern` function \
|
||||
@ -578,7 +578,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let sig = cx.erase_late_bound_regions(&bare_fn.sig);
|
||||
let sig = cx.erase_late_bound_regions(&sig);
|
||||
if !sig.output().is_nil() {
|
||||
let r = self.check_type_for_ffi(cache, sig.output());
|
||||
match r {
|
||||
|
@ -363,12 +363,6 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::BareFnTy<'tcx>> for DecodeContext<'a, 'tcx> {
|
||||
fn specialized_decode(&mut self) -> Result<&'tcx ty::BareFnTy<'tcx>, Self::Error> {
|
||||
Ok(self.tcx().mk_bare_fn(Decodable::decode(self)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::AdtDef> for DecodeContext<'a, 'tcx> {
|
||||
fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> {
|
||||
let def_id = DefId::decode(self)?;
|
||||
@ -1054,7 +1048,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
pub fn closure_ty(&self,
|
||||
closure_id: DefIndex,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> ty::ClosureTy<'tcx> {
|
||||
-> ty::PolyFnSig<'tcx> {
|
||||
match self.entry(closure_id).kind {
|
||||
EntryKind::Closure(data) => data.decode(self).ty.decode((self, tcx)),
|
||||
_ => bug!(),
|
||||
|
@ -337,5 +337,5 @@ pub struct MethodData {
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
pub struct ClosureData<'tcx> {
|
||||
pub kind: ty::ClosureKind,
|
||||
pub ty: Lazy<ty::ClosureTy<'tcx>>,
|
||||
pub ty: Lazy<ty::PolyFnSig<'tcx>>,
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
let diverges = match ty.sty {
|
||||
ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => {
|
||||
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
||||
f.sig.skip_binder().output().is_never()
|
||||
f.output().skip_binder().is_never()
|
||||
}
|
||||
_ => false
|
||||
};
|
||||
|
@ -267,13 +267,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
let method = method_callee(cx, expr, ty::MethodCall::expr(expr.id));
|
||||
|
||||
let sig = match method.ty.sty {
|
||||
ty::TyFnDef(.., fn_ty) => &fn_ty.sig,
|
||||
_ => span_bug!(expr.span, "type of method is not an fn"),
|
||||
};
|
||||
let sig = method.ty.fn_sig();
|
||||
|
||||
let sig = cx.tcx
|
||||
.no_late_bound_regions(sig)
|
||||
.no_late_bound_regions(&sig)
|
||||
.unwrap_or_else(|| span_bug!(expr.span, "method call has late-bound regions"));
|
||||
|
||||
assert_eq!(sig.inputs().len(), 2);
|
||||
|
@ -104,10 +104,14 @@ fn build_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
||||
let fn_sig = cx.tables().liberated_fn_sigs[&id].clone();
|
||||
|
||||
let ty = tcx.item_type(tcx.hir.local_def_id(id));
|
||||
let (abi, implicit_argument) = if let ty::TyClosure(..) = ty.sty {
|
||||
(Abi::Rust, Some((closure_self_ty(tcx, id, body_id), None)))
|
||||
let mut abi = fn_sig.abi;
|
||||
let implicit_argument = if let ty::TyClosure(..) = ty.sty {
|
||||
// HACK(eddyb) Avoid having RustCall on closures,
|
||||
// as it adds unnecessary (and wrong) auto-tupling.
|
||||
abi = Abi::Rust;
|
||||
Some((closure_self_ty(tcx, id, body_id), None))
|
||||
} else {
|
||||
(ty.fn_abi(), None)
|
||||
None
|
||||
};
|
||||
|
||||
let body = tcx.hir.body(body_id);
|
||||
|
@ -788,7 +788,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
||||
let fn_ty = func.ty(self.mir, self.tcx);
|
||||
let (is_shuffle, is_const_fn) = match fn_ty.sty {
|
||||
ty::TyFnDef(def_id, _, f) => {
|
||||
(f.abi == Abi::PlatformIntrinsic &&
|
||||
(f.abi() == Abi::PlatformIntrinsic &&
|
||||
self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
|
||||
is_const_fn(self.tcx, def_id))
|
||||
}
|
||||
|
@ -440,14 +440,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
TerminatorKind::Call { ref func, ref args, ref destination, .. } => {
|
||||
let func_ty = func.ty(mir, tcx);
|
||||
debug!("check_terminator: call, func_ty={:?}", func_ty);
|
||||
let func_ty = match func_ty.sty {
|
||||
ty::TyFnDef(.., func_ty) | ty::TyFnPtr(func_ty) => func_ty,
|
||||
let sig = match func_ty.sty {
|
||||
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => sig,
|
||||
_ => {
|
||||
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let sig = tcx.erase_late_bound_regions(&func_ty.sig);
|
||||
let sig = tcx.erase_late_bound_regions(&sig);
|
||||
let sig = self.normalize(&sig);
|
||||
self.check_call_dest(mir, term, &sig, destination);
|
||||
|
||||
|
@ -327,20 +327,18 @@ pub struct FnType {
|
||||
|
||||
impl FnType {
|
||||
pub fn new<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
abi: Abi,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
extra_args: &[Ty<'tcx>]) -> FnType {
|
||||
let mut fn_ty = FnType::unadjusted(ccx, abi, sig, extra_args);
|
||||
fn_ty.adjust_for_abi(ccx, abi, sig);
|
||||
let mut fn_ty = FnType::unadjusted(ccx, sig, extra_args);
|
||||
fn_ty.adjust_for_abi(ccx, sig);
|
||||
fn_ty
|
||||
}
|
||||
|
||||
pub fn unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
abi: Abi,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
extra_args: &[Ty<'tcx>]) -> FnType {
|
||||
use self::Abi::*;
|
||||
let cconv = match ccx.sess().target.target.adjust_abi(abi) {
|
||||
let cconv = match ccx.sess().target.target.adjust_abi(sig.abi) {
|
||||
RustIntrinsic | PlatformIntrinsic |
|
||||
Rust | RustCall => llvm::CCallConv,
|
||||
|
||||
@ -363,7 +361,7 @@ impl FnType {
|
||||
};
|
||||
|
||||
let mut inputs = sig.inputs();
|
||||
let extra_args = if abi == RustCall {
|
||||
let extra_args = if sig.abi == RustCall {
|
||||
assert!(!sig.variadic && extra_args.is_empty());
|
||||
|
||||
match sig.inputs().last().unwrap().sty {
|
||||
@ -388,7 +386,7 @@ impl FnType {
|
||||
let linux_s390x = target.target_os == "linux"
|
||||
&& target.arch == "s390x"
|
||||
&& target.target_env == "gnu";
|
||||
let rust_abi = match abi {
|
||||
let rust_abi = match sig.abi {
|
||||
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true,
|
||||
_ => false
|
||||
};
|
||||
@ -535,8 +533,8 @@ impl FnType {
|
||||
|
||||
pub fn adjust_for_abi<'a, 'tcx>(&mut self,
|
||||
ccx: &CrateContext<'a, 'tcx>,
|
||||
abi: Abi,
|
||||
sig: &ty::FnSig<'tcx>) {
|
||||
sig: ty::FnSig<'tcx>) {
|
||||
let abi = sig.abi;
|
||||
if abi == Abi::Unadjusted { return }
|
||||
|
||||
if abi == Abi::Rust || abi == Abi::RustCall ||
|
||||
|
@ -47,7 +47,7 @@ use rustc::util::common::time;
|
||||
use session::config::{self, NoDebugInfo};
|
||||
use rustc_incremental::IncrementalHashesMap;
|
||||
use session::{self, DataTypeKind, Session};
|
||||
use abi::{self, Abi, FnType};
|
||||
use abi::{self, FnType};
|
||||
use mir::lvalue::LvalueRef;
|
||||
use adt;
|
||||
use attributes;
|
||||
@ -600,8 +600,8 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
|
||||
let fn_ty = ccx.tcx().erase_regions(&fn_ty);
|
||||
let fn_ty = monomorphize::apply_param_substs(ccx.shared(), instance.substs, &fn_ty);
|
||||
|
||||
let ty::BareFnTy { abi, ref sig, .. } = *common::ty_fn_ty(ccx, fn_ty);
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(sig);
|
||||
let sig = common::ty_fn_sig(ccx, fn_ty);
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
||||
|
||||
let lldecl = match ccx.instances().borrow().get(&instance) {
|
||||
Some(&val) => val,
|
||||
@ -614,10 +614,8 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
|
||||
attributes::emit_uwtable(lldecl, true);
|
||||
}
|
||||
|
||||
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
|
||||
|
||||
let mir = ccx.tcx().item_mir(instance.def);
|
||||
mir::trans_mir(ccx, lldecl, fn_ty, &mir, instance, &sig, abi);
|
||||
mir::trans_mir(ccx, lldecl, &mir, instance, sig);
|
||||
}
|
||||
|
||||
pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
@ -632,7 +630,7 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
let ctor_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &ctor_ty);
|
||||
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig());
|
||||
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
|
||||
let fn_ty = FnType::new(ccx, sig, &[]);
|
||||
|
||||
let bcx = Builder::new_block(ccx, llfn, "entry-block");
|
||||
if !fn_ty.ret.is_ignore() {
|
||||
|
@ -83,7 +83,7 @@ impl<'tcx> Callee<'tcx> {
|
||||
|
||||
let fn_ty = def_ty(ccx.shared(), def_id, substs);
|
||||
if let ty::TyFnDef(.., f) = fn_ty.sty {
|
||||
if f.abi == Abi::RustIntrinsic || f.abi == Abi::PlatformIntrinsic {
|
||||
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
|
||||
return Callee {
|
||||
data: Intrinsic,
|
||||
ty: fn_ty
|
||||
@ -169,14 +169,13 @@ impl<'tcx> Callee<'tcx> {
|
||||
/// The extra argument types are for variadic (extern "C") functions.
|
||||
pub fn direct_fn_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>,
|
||||
extra_args: &[Ty<'tcx>]) -> FnType {
|
||||
let abi = self.ty.fn_abi();
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(self.ty.fn_sig());
|
||||
let mut fn_ty = FnType::unadjusted(ccx, abi, &sig, extra_args);
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&self.ty.fn_sig());
|
||||
let mut fn_ty = FnType::unadjusted(ccx, sig, extra_args);
|
||||
if let Virtual(_) = self.data {
|
||||
// Don't pass the vtable, it's not an argument of the virtual fn.
|
||||
fn_ty.args[1].ignore();
|
||||
}
|
||||
fn_ty.adjust_for_abi(ccx, abi, &sig);
|
||||
fn_ty.adjust_for_abi(ccx, sig);
|
||||
fn_ty
|
||||
}
|
||||
|
||||
@ -307,38 +306,32 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
||||
let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), closure_ty);
|
||||
|
||||
// Make a version with the type of by-ref closure.
|
||||
let ty::ClosureTy { unsafety, abi, mut sig } = tcx.closure_type(def_id, substs);
|
||||
sig.0 = tcx.mk_fn_sig(
|
||||
iter::once(ref_closure_ty).chain(sig.0.inputs().iter().cloned()),
|
||||
sig.0.output(),
|
||||
sig.0.variadic
|
||||
);
|
||||
let llref_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
sig: sig.clone()
|
||||
}));
|
||||
let sig = tcx.closure_type(def_id, substs);
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
assert_eq!(sig.abi, Abi::RustCall);
|
||||
let llref_fn_ty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
|
||||
iter::once(ref_closure_ty).chain(sig.inputs().iter().cloned()),
|
||||
sig.output(),
|
||||
sig.variadic,
|
||||
sig.unsafety,
|
||||
Abi::RustCall
|
||||
)));
|
||||
debug!("trans_fn_once_adapter_shim: llref_fn_ty={:?}",
|
||||
llref_fn_ty);
|
||||
|
||||
|
||||
// Make a version of the closure type with the same arguments, but
|
||||
// with argument #0 being by value.
|
||||
assert_eq!(abi, Abi::RustCall);
|
||||
sig.0 = tcx.mk_fn_sig(
|
||||
iter::once(closure_ty).chain(sig.0.inputs().iter().skip(1).cloned()),
|
||||
sig.0.output(),
|
||||
sig.0.variadic
|
||||
let sig = tcx.mk_fn_sig(
|
||||
iter::once(closure_ty).chain(sig.inputs().iter().cloned()),
|
||||
sig.output(),
|
||||
sig.variadic,
|
||||
sig.unsafety,
|
||||
Abi::RustCall
|
||||
);
|
||||
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
|
||||
|
||||
let llonce_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
sig: ty::Binder(sig)
|
||||
}));
|
||||
let fn_ty = FnType::new(ccx, sig, &[]);
|
||||
let llonce_fn_ty = tcx.mk_fn_ptr(ty::Binder(sig));
|
||||
|
||||
// Create the by-value helper.
|
||||
let function_name = method_instance.symbol_name(ccx.shared());
|
||||
@ -470,33 +463,20 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
|
||||
|
||||
// Construct the "tuply" version of `bare_fn_ty`. It takes two arguments: `self`,
|
||||
// which is the fn pointer, and `args`, which is the arguments tuple.
|
||||
let sig = match bare_fn_ty.sty {
|
||||
ty::TyFnDef(..,
|
||||
&ty::BareFnTy { unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
ref sig }) |
|
||||
ty::TyFnPtr(&ty::BareFnTy { unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
ref sig }) => sig,
|
||||
|
||||
_ => {
|
||||
bug!("trans_fn_pointer_shim invoked on invalid type: {}",
|
||||
bare_fn_ty);
|
||||
}
|
||||
};
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
|
||||
let sig = bare_fn_ty.fn_sig();
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
assert_eq!(sig.unsafety, hir::Unsafety::Normal);
|
||||
assert_eq!(sig.abi, Abi::Rust);
|
||||
let tuple_input_ty = tcx.intern_tup(sig.inputs(), false);
|
||||
let sig = tcx.mk_fn_sig(
|
||||
[bare_fn_ty_maybe_ref, tuple_input_ty].iter().cloned(),
|
||||
sig.output(),
|
||||
false
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::RustCall
|
||||
);
|
||||
let fn_ty = FnType::new(ccx, Abi::RustCall, &sig, &[]);
|
||||
let tuple_fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::RustCall,
|
||||
sig: ty::Binder(sig)
|
||||
}));
|
||||
let fn_ty = FnType::new(ccx, sig, &[]);
|
||||
let tuple_fn_ty = tcx.mk_fn_ptr(ty::Binder(sig));
|
||||
debug!("tuple_fn_ty: {:?}", tuple_fn_ty);
|
||||
|
||||
//
|
||||
@ -600,7 +580,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
// other weird situations. Annoying.
|
||||
|
||||
// Create a fn pointer with the substituted signature.
|
||||
let fn_ptr_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(common::ty_fn_ty(ccx, fn_ty).into_owned()));
|
||||
let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(ccx, fn_ty));
|
||||
let llptrty = type_of::type_of(ccx, fn_ptr_ty);
|
||||
|
||||
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
||||
|
@ -682,10 +682,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
|
||||
fn is_drop_in_place_intrinsic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
bare_fn_ty: &ty::BareFnTy<'tcx>)
|
||||
bare_fn_ty: ty::PolyFnSig<'tcx>)
|
||||
-> bool {
|
||||
(bare_fn_ty.abi == Abi::RustIntrinsic ||
|
||||
bare_fn_ty.abi == Abi::PlatformIntrinsic) &&
|
||||
(bare_fn_ty.abi() == Abi::RustIntrinsic ||
|
||||
bare_fn_ty.abi() == Abi::PlatformIntrinsic) &&
|
||||
tcx.item_name(def_id) == "drop_in_place"
|
||||
}
|
||||
}
|
||||
@ -697,8 +697,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> bool {
|
||||
if let ty::TyFnDef(_, _, f) = tcx.item_type(def_id).sty {
|
||||
if let Some(adt_def) = f.sig.output().skip_binder().ty_adt_def() {
|
||||
if let ty::TyFnDef(_, _, sig) = tcx.item_type(def_id).sty {
|
||||
if let Some(adt_def) = sig.output().skip_binder().ty_adt_def() {
|
||||
if adt_def.variants.iter().any(|v| def_id == v.did) {
|
||||
// HACK: ADT constructors are translated in-place and
|
||||
// do not have a trans-item.
|
||||
|
@ -33,7 +33,6 @@ use rustc::traits::{self, SelectionContext, Reveal};
|
||||
use rustc::hir;
|
||||
|
||||
use libc::{c_uint, c_char};
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
|
||||
use syntax::ast;
|
||||
@ -570,17 +569,17 @@ pub fn shift_mask_val<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ty_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> Cow<'tcx, ty::BareFnTy<'tcx>>
|
||||
pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> ty::PolyFnSig<'tcx>
|
||||
{
|
||||
match ty.sty {
|
||||
ty::TyFnDef(_, _, fty) => Cow::Borrowed(fty),
|
||||
ty::TyFnDef(_, _, sig) => sig,
|
||||
// Shims currently have type TyFnPtr. Not sure this should remain.
|
||||
ty::TyFnPtr(fty) => Cow::Borrowed(fty),
|
||||
ty::TyFnPtr(sig) => sig,
|
||||
ty::TyClosure(def_id, substs) => {
|
||||
let tcx = ccx.tcx();
|
||||
let ty::ClosureTy { unsafety, abi, sig } = tcx.closure_type(def_id, substs);
|
||||
let sig = tcx.closure_type(def_id, substs);
|
||||
|
||||
let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv);
|
||||
let env_ty = match tcx.closure_kind(def_id) {
|
||||
@ -589,12 +588,13 @@ pub fn ty_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ty::ClosureKind::FnOnce => ty,
|
||||
};
|
||||
|
||||
let sig = sig.map_bound(|sig| tcx.mk_fn_sig(
|
||||
sig.map_bound(|sig| tcx.mk_fn_sig(
|
||||
iter::once(env_ty).chain(sig.inputs().iter().cloned()),
|
||||
sig.output(),
|
||||
sig.variadic
|
||||
));
|
||||
Cow::Owned(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: sig })
|
||||
sig.variadic,
|
||||
sig.unsafety,
|
||||
sig.abi
|
||||
))
|
||||
}
|
||||
_ => bug!("unexpected type {:?} to ty_fn_sig", ty)
|
||||
}
|
||||
|
@ -959,15 +959,13 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
return llfn;
|
||||
}
|
||||
|
||||
let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
abi: Abi::C,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(
|
||||
iter::once(tcx.mk_mut_ptr(tcx.types.u8)),
|
||||
tcx.types.never,
|
||||
false
|
||||
)),
|
||||
}));
|
||||
let ty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
|
||||
iter::once(tcx.mk_mut_ptr(tcx.types.u8)),
|
||||
tcx.types.never,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::C
|
||||
)));
|
||||
|
||||
let llfn = declare::declare_fn(self, "rust_eh_unwind_resume", ty);
|
||||
attributes::unwind(llfn, true);
|
||||
|
@ -373,11 +373,11 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
unique_type_id: UniqueTypeId,
|
||||
signature: &ty::PolyFnSig<'tcx>,
|
||||
signature: ty::PolyFnSig<'tcx>,
|
||||
span: Span)
|
||||
-> MetadataCreationResult
|
||||
{
|
||||
let signature = cx.tcx().erase_late_bound_regions(signature);
|
||||
let signature = cx.tcx().erase_late_bound_regions(&signature);
|
||||
|
||||
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1);
|
||||
|
||||
@ -558,10 +558,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
Err(metadata) => return metadata,
|
||||
}
|
||||
}
|
||||
ty::TyFnDef(.., ref barefnty) | ty::TyFnPtr(ref barefnty) => {
|
||||
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => {
|
||||
let fn_metadata = subroutine_type_metadata(cx,
|
||||
unique_type_id,
|
||||
&barefnty.sig,
|
||||
sig,
|
||||
usage_site_span).metadata;
|
||||
match debug_context(cx).type_map
|
||||
.borrow()
|
||||
|
@ -198,8 +198,7 @@ pub fn finalize(cx: &CrateContext) {
|
||||
/// for the function.
|
||||
pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
abi: Abi,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
llfn: ValueRef,
|
||||
mir: &mir::Mir) -> FunctionDebugContext {
|
||||
if cx.sess().opts.debuginfo == NoDebugInfo {
|
||||
@ -225,7 +224,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
let file_metadata = file_metadata(cx, &loc.file.name, &loc.file.abs_path);
|
||||
|
||||
let function_type_metadata = unsafe {
|
||||
let fn_signature = get_function_signature(cx, sig, abi);
|
||||
let fn_signature = get_function_signature(cx, sig);
|
||||
llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
|
||||
};
|
||||
|
||||
@ -295,8 +294,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
return FunctionDebugContext::RegularContext(fn_debug_context);
|
||||
|
||||
fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
abi: Abi) -> DIArray {
|
||||
sig: ty::FnSig<'tcx>) -> DIArray {
|
||||
if cx.sess().opts.debuginfo == LimitedDebugInfo {
|
||||
return create_DIArray(DIB(cx), &[]);
|
||||
}
|
||||
@ -309,7 +307,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
_ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP)
|
||||
});
|
||||
|
||||
let inputs = if abi == Abi::RustCall {
|
||||
let inputs = if sig.abi == Abi::RustCall {
|
||||
&sig.inputs()[..sig.inputs().len() - 1]
|
||||
} else {
|
||||
sig.inputs()
|
||||
@ -320,7 +318,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP));
|
||||
}
|
||||
|
||||
if abi == Abi::RustCall && !sig.inputs().is_empty() {
|
||||
if sig.abi == Abi::RustCall && !sig.inputs().is_empty() {
|
||||
if let ty::TyTuple(args, _) = sig.inputs()[sig.inputs().len() - 1].sty {
|
||||
for &argument_type in args {
|
||||
signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP));
|
||||
|
@ -96,12 +96,13 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
push_type_params(cx, principal.substs, output);
|
||||
}
|
||||
},
|
||||
ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) |
|
||||
ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
|
||||
if unsafety == hir::Unsafety::Unsafe {
|
||||
ty::TyFnDef(.., sig) |
|
||||
ty::TyFnPtr(sig) => {
|
||||
if sig.unsafety() == hir::Unsafety::Unsafe {
|
||||
output.push_str("unsafe ");
|
||||
}
|
||||
|
||||
let abi = sig.abi();
|
||||
if abi != ::abi::Abi::Rust {
|
||||
output.push_str("extern \"");
|
||||
output.push_str(abi.name());
|
||||
@ -110,7 +111,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
output.push_str("fn(");
|
||||
|
||||
let sig = cx.tcx().erase_late_bound_regions_and_normalize(sig);
|
||||
let sig = cx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
||||
if !sig.inputs().is_empty() {
|
||||
for ¶meter_type in sig.inputs() {
|
||||
push_debuginfo_type_name(cx, parameter_type, true, output);
|
||||
|
@ -132,11 +132,11 @@ pub fn declare_cfn(ccx: &CrateContext, name: &str, fn_type: Type) -> ValueRef {
|
||||
pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
|
||||
fn_type: ty::Ty<'tcx>) -> ValueRef {
|
||||
debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type);
|
||||
let ty::BareFnTy { abi, ref sig, .. } = *common::ty_fn_ty(ccx, fn_type);
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(sig);
|
||||
let sig = common::ty_fn_sig(ccx, fn_type);
|
||||
let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
||||
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
|
||||
|
||||
let fty = FnType::new(ccx, abi, &sig, &[]);
|
||||
let fty = FnType::new(ccx, sig, &[]);
|
||||
let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx));
|
||||
|
||||
// FIXME(canndrew): This is_never should really be an is_uninhabited
|
||||
@ -144,7 +144,7 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
|
||||
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
|
||||
}
|
||||
|
||||
if abi != Abi::Rust && abi != Abi::RustCall {
|
||||
if sig.abi != Abi::Rust && sig.abi != Abi::RustCall {
|
||||
attributes::unwind(llfn, false);
|
||||
}
|
||||
|
||||
|
@ -97,12 +97,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let ccx = bcx.ccx;
|
||||
let tcx = ccx.tcx();
|
||||
|
||||
let (def_id, substs, fty) = match callee_ty.sty {
|
||||
ty::TyFnDef(def_id, substs, ref fty) => (def_id, substs, fty),
|
||||
let (def_id, substs, sig) = match callee_ty.sty {
|
||||
ty::TyFnDef(def_id, substs, sig) => (def_id, substs, sig),
|
||||
_ => bug!("expected fn item type, found {}", callee_ty)
|
||||
};
|
||||
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&fty.sig);
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
let arg_tys = sig.inputs();
|
||||
let ret_ty = sig.output();
|
||||
let name = &*tcx.item_name(def_id).as_str();
|
||||
@ -878,13 +878,13 @@ fn gen_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
output: Ty<'tcx>,
|
||||
trans: &mut for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
-> ValueRef {
|
||||
let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false);
|
||||
|
||||
let rust_fn_ty = ccx.tcx().mk_fn_ptr(ccx.tcx().mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
abi: Abi::Rust,
|
||||
sig: ty::Binder(sig)
|
||||
}));
|
||||
let rust_fn_ty = ccx.tcx().mk_fn_ptr(ty::Binder(ccx.tcx().mk_fn_sig(
|
||||
inputs.into_iter(),
|
||||
output,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust
|
||||
)));
|
||||
let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
|
||||
let bcx = Builder::new_block(ccx, llfn, "entry-block");
|
||||
trans(bcx);
|
||||
@ -905,11 +905,13 @@ fn get_rust_try_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
// Define the type up front for the signature of the rust_try function.
|
||||
let tcx = ccx.tcx();
|
||||
let i8p = tcx.mk_mut_ptr(tcx.types.i8);
|
||||
let fn_ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
abi: Abi::Rust,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(iter::once(i8p), tcx.mk_nil(), false)),
|
||||
}));
|
||||
let fn_ty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
|
||||
iter::once(i8p),
|
||||
tcx.mk_nil(),
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust
|
||||
)));
|
||||
let output = tcx.types.i32;
|
||||
let rust_try = gen_fn(ccx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans);
|
||||
ccx.rust_try_fn().set(Some(rust_try));
|
||||
@ -959,7 +961,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
||||
|
||||
|
||||
let tcx = bcx.tcx();
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(callee_ty.fn_sig());
|
||||
let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig());
|
||||
let arg_tys = sig.inputs();
|
||||
|
||||
// every intrinsic takes a SIMD vector as its first argument
|
||||
|
@ -365,20 +365,21 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
|
||||
let callee = self.trans_operand(&bcx, func);
|
||||
|
||||
let (mut callee, abi, sig) = match callee.ty.sty {
|
||||
ty::TyFnDef(def_id, substs, f) => {
|
||||
(Callee::def(bcx.ccx, def_id, substs), f.abi, &f.sig)
|
||||
let (mut callee, sig) = match callee.ty.sty {
|
||||
ty::TyFnDef(def_id, substs, sig) => {
|
||||
(Callee::def(bcx.ccx, def_id, substs), sig)
|
||||
}
|
||||
ty::TyFnPtr(f) => {
|
||||
ty::TyFnPtr(sig) => {
|
||||
(Callee {
|
||||
data: Fn(callee.immediate()),
|
||||
ty: callee.ty
|
||||
}, f.abi, &f.sig)
|
||||
}, sig)
|
||||
}
|
||||
_ => bug!("{} is not callable", callee.ty)
|
||||
};
|
||||
|
||||
let sig = bcx.tcx().erase_late_bound_regions_and_normalize(sig);
|
||||
let sig = bcx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
||||
let abi = sig.abi;
|
||||
|
||||
// Handle intrinsics old trans wants Expr's for, ourselves.
|
||||
let intrinsic = match (&callee.ty.sty, &callee.data) {
|
||||
|
@ -588,7 +588,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
.find(|it| it.kind == ty::AssociatedKind::Method)
|
||||
.unwrap().def_id;
|
||||
// Now create its substs [Closure, Tuple]
|
||||
let input = tcx.closure_type(def_id, substs).sig.input(0);
|
||||
let input = tcx.closure_type(def_id, substs).input(0);
|
||||
let substs = tcx.mk_substs([operand.ty, input.skip_binder()]
|
||||
.iter().cloned().map(Kind::from));
|
||||
Callee::def(self.ccx, call_once, substs)
|
||||
|
@ -28,7 +28,6 @@ use type_of;
|
||||
|
||||
use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos, Span};
|
||||
use syntax::symbol::keywords;
|
||||
use syntax::abi::Abi;
|
||||
|
||||
use std::iter;
|
||||
|
||||
@ -205,15 +204,14 @@ impl<'tcx> LocalRef<'tcx> {
|
||||
pub fn trans_mir<'a, 'tcx: 'a>(
|
||||
ccx: &'a CrateContext<'a, 'tcx>,
|
||||
llfn: ValueRef,
|
||||
fn_ty: FnType,
|
||||
mir: &'a Mir<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
abi: Abi,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
) {
|
||||
let fn_ty = FnType::new(ccx, sig, &[]);
|
||||
debug!("fn_ty: {:?}", fn_ty);
|
||||
let debug_context =
|
||||
debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfn, mir);
|
||||
debuginfo::create_function_debug_context(ccx, instance, sig, llfn, mir);
|
||||
let bcx = Builder::new_block(ccx, llfn, "entry-block");
|
||||
|
||||
let cleanup_kinds = analyze::cleanup_kinds(&mir);
|
||||
|
@ -201,7 +201,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
.find(|it| it.kind == ty::AssociatedKind::Method)
|
||||
.unwrap().def_id;
|
||||
// Now create its substs [Closure, Tuple]
|
||||
let input = bcx.tcx().closure_type(def_id, substs).sig.input(0);
|
||||
let input = bcx.tcx().closure_type(def_id, substs).input(0);
|
||||
let substs = bcx.tcx().mk_substs([operand.ty, input.skip_binder()]
|
||||
.iter().cloned().map(Kind::from));
|
||||
OperandValue::Immediate(
|
||||
|
@ -199,11 +199,17 @@ impl<'a, 'tcx> TransItem<'tcx> {
|
||||
assert_eq!(dg.ty(), glue::get_drop_glue_type(ccx.shared(), dg.ty()));
|
||||
let t = dg.ty();
|
||||
|
||||
let sig = tcx.mk_fn_sig(iter::once(tcx.mk_mut_ptr(t)), tcx.mk_nil(), false);
|
||||
let sig = tcx.mk_fn_sig(
|
||||
iter::once(tcx.mk_mut_ptr(t)),
|
||||
tcx.mk_nil(),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust
|
||||
);
|
||||
|
||||
debug!("predefine_drop_glue: sig={}", sig);
|
||||
|
||||
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
|
||||
let fn_ty = FnType::new(ccx, sig, &[]);
|
||||
let llfnty = fn_ty.llvm_type(ccx);
|
||||
|
||||
assert!(declare::get_defined_value(ccx, symbol_name).is_none());
|
||||
@ -457,12 +463,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
||||
output);
|
||||
}
|
||||
},
|
||||
ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) |
|
||||
ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => {
|
||||
if unsafety == hir::Unsafety::Unsafe {
|
||||
ty::TyFnDef(.., sig) |
|
||||
ty::TyFnPtr(sig) => {
|
||||
if sig.unsafety() == hir::Unsafety::Unsafe {
|
||||
output.push_str("unsafe ");
|
||||
}
|
||||
|
||||
let abi = sig.abi();
|
||||
if abi != ::abi::Abi::Rust {
|
||||
output.push_str("extern \"");
|
||||
output.push_str(abi.name());
|
||||
@ -471,7 +478,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
||||
|
||||
output.push_str("fn(");
|
||||
|
||||
let sig = self.tcx.erase_late_bound_regions_and_normalize(sig);
|
||||
let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||
|
||||
if !sig.inputs().is_empty() {
|
||||
for ¶meter_type in sig.inputs() {
|
||||
|
@ -272,9 +272,9 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
|
||||
ty::TyStr | ty::TyDynamic(..) => Type::i8(cx),
|
||||
|
||||
ty::TyFnDef(..) => Type::nil(cx),
|
||||
ty::TyFnPtr(f) => {
|
||||
let sig = cx.tcx().erase_late_bound_regions_and_normalize(&f.sig);
|
||||
FnType::new(cx, f.abi, &sig, &[]).llvm_type(cx).ptr_to()
|
||||
ty::TyFnPtr(sig) => {
|
||||
let sig = cx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
||||
FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to()
|
||||
}
|
||||
ty::TyTuple(ref tys, _) if tys.is_empty() => Type::nil(cx),
|
||||
ty::TyTuple(..) => {
|
||||
|
@ -1116,10 +1116,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// warning then. (Once we fix #32330, the regions we are
|
||||
// checking for here would be considered early bound
|
||||
// anyway.)
|
||||
let inputs = bare_fn_ty.sig.inputs();
|
||||
let inputs = bare_fn_ty.inputs();
|
||||
let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
|
||||
&inputs.map_bound(|i| i.to_owned()));
|
||||
let output = bare_fn_ty.sig.output();
|
||||
let output = bare_fn_ty.output();
|
||||
let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
|
||||
for br in late_bound_in_ret.difference(&late_bound_in_args) {
|
||||
let br_name = match *br {
|
||||
@ -1272,7 +1272,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
unsafety: hir::Unsafety,
|
||||
abi: abi::Abi,
|
||||
decl: &hir::FnDecl)
|
||||
-> &'tcx ty::BareFnTy<'tcx> {
|
||||
-> ty::PolyFnSig<'tcx> {
|
||||
debug!("ty_of_fn");
|
||||
|
||||
let input_tys: Vec<Ty> =
|
||||
@ -1285,15 +1285,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
debug!("ty_of_fn: output_ty={:?}", output_ty);
|
||||
|
||||
self.tcx().mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
sig: ty::Binder(self.tcx().mk_fn_sig(
|
||||
input_tys.into_iter(),
|
||||
output_ty,
|
||||
decl.variadic
|
||||
)),
|
||||
})
|
||||
ty::Binder(self.tcx().mk_fn_sig(
|
||||
input_tys.into_iter(),
|
||||
output_ty,
|
||||
decl.variadic,
|
||||
unsafety,
|
||||
abi
|
||||
))
|
||||
}
|
||||
|
||||
pub fn ty_of_closure(&self,
|
||||
@ -1301,7 +1299,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
decl: &hir::FnDecl,
|
||||
abi: abi::Abi,
|
||||
expected_sig: Option<ty::FnSig<'tcx>>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
-> ty::PolyFnSig<'tcx>
|
||||
{
|
||||
debug!("ty_of_closure(expected_sig={:?})",
|
||||
expected_sig);
|
||||
@ -1338,11 +1336,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
debug!("ty_of_closure: output_ty={:?}", output_ty);
|
||||
|
||||
ty::ClosureTy {
|
||||
unsafety: unsafety,
|
||||
abi: abi,
|
||||
sig: ty::Binder(self.tcx().mk_fn_sig(input_tys, output_ty, decl.variadic)),
|
||||
}
|
||||
ty::Binder(self.tcx().mk_fn_sig(
|
||||
input_tys,
|
||||
output_ty,
|
||||
decl.variadic,
|
||||
unsafety,
|
||||
abi
|
||||
))
|
||||
}
|
||||
|
||||
/// Given the bounds on an object, determines what single region bound (if any) we can
|
||||
|
@ -14,6 +14,7 @@ use hir::def::Def;
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::{infer, traits};
|
||||
use rustc::ty::{self, TyCtxt, LvaluePreference, Ty};
|
||||
use syntax::abi;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
|
||||
@ -112,7 +113,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let closure_ty = self.closure_type(def_id, substs);
|
||||
let fn_sig = self.replace_late_bound_regions_with_fresh_var(call_expr.span,
|
||||
infer::FnCall,
|
||||
&closure_ty.sig)
|
||||
&closure_ty)
|
||||
.0;
|
||||
self.record_deferred_call_resolution(def_id,
|
||||
Box::new(CallResolution {
|
||||
@ -186,13 +187,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
arg_exprs: &'gcx [hir::Expr],
|
||||
expected: Expectation<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
let error_fn_sig;
|
||||
|
||||
let (fn_sig, def_span) = match callee_ty.sty {
|
||||
ty::TyFnDef(def_id, .., &ty::BareFnTy {ref sig, ..}) => {
|
||||
ty::TyFnDef(def_id, .., sig) => {
|
||||
(sig, self.tcx.hir.span_if_local(def_id))
|
||||
}
|
||||
ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => (sig, None),
|
||||
ty::TyFnPtr(sig) => (sig, None),
|
||||
ref t => {
|
||||
let mut unit_variant = None;
|
||||
if let &ty::TyAdt(adt_def, ..) = t {
|
||||
@ -232,13 +231,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// This is the "default" function signature, used in case of error.
|
||||
// In that case, we check each argument against "error" in order to
|
||||
// set up all the node type bindings.
|
||||
error_fn_sig = ty::Binder(self.tcx.mk_fn_sig(
|
||||
(ty::Binder(self.tcx.mk_fn_sig(
|
||||
self.err_args(arg_exprs.len()).into_iter(),
|
||||
self.tcx.types.err,
|
||||
false,
|
||||
));
|
||||
|
||||
(&error_fn_sig, None)
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust
|
||||
)), None)
|
||||
}
|
||||
};
|
||||
|
||||
@ -248,7 +247,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// previously appeared within a `Binder<>` and hence would not
|
||||
// have been normalized before.
|
||||
let fn_sig =
|
||||
self.replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, fn_sig)
|
||||
self.replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, &fn_sig)
|
||||
.0;
|
||||
let fn_sig = self.normalize_associated_types_in(call_expr.span, &fn_sig);
|
||||
|
||||
@ -355,7 +354,7 @@ impl<'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> for CallResolution<'gcx, 'tc
|
||||
// (This always bites me, should find a way to
|
||||
// refactor it.)
|
||||
let method_sig = fcx.tcx
|
||||
.no_late_bound_regions(method_callee.ty.fn_sig())
|
||||
.no_late_bound_regions(&method_callee.ty.fn_sig())
|
||||
.unwrap();
|
||||
|
||||
debug!("attempt_resolution: method_callee={:?}", method_callee);
|
||||
|
@ -55,11 +55,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
expected_sig);
|
||||
|
||||
let expr_def_id = self.tcx.hir.local_def_id(expr.id);
|
||||
let mut fn_ty = AstConv::ty_of_closure(self,
|
||||
hir::Unsafety::Normal,
|
||||
decl,
|
||||
Abi::RustCall,
|
||||
expected_sig);
|
||||
let sig = AstConv::ty_of_closure(self,
|
||||
hir::Unsafety::Normal,
|
||||
decl,
|
||||
Abi::RustCall,
|
||||
expected_sig);
|
||||
|
||||
// Create type variables (for now) to represent the transformed
|
||||
// types of upvars. These will be unified during the upvar
|
||||
@ -74,32 +74,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
|
||||
|
||||
let extent = self.tcx.region_maps.call_site_extent(expr.id, body.value.id);
|
||||
let fn_sig = self.tcx.liberate_late_bound_regions(extent, &fn_ty.sig);
|
||||
let fn_sig = self.tcx.liberate_late_bound_regions(extent, &sig);
|
||||
let fn_sig = self.inh.normalize_associated_types_in(body.value.span,
|
||||
body.value.id, &fn_sig);
|
||||
|
||||
check_fn(self,
|
||||
hir::Unsafety::Normal,
|
||||
expr.id,
|
||||
&fn_sig,
|
||||
decl,
|
||||
expr.id,
|
||||
body);
|
||||
check_fn(self, fn_sig, decl, expr.id, body);
|
||||
|
||||
// Tuple up the arguments and insert the resulting function type into
|
||||
// the `closures` table.
|
||||
fn_ty.sig.0 = self.tcx.mk_fn_sig(
|
||||
iter::once(self.tcx.intern_tup(fn_ty.sig.skip_binder().inputs(), false)),
|
||||
fn_ty.sig.skip_binder().output(),
|
||||
fn_ty.sig.variadic()
|
||||
);
|
||||
let sig = sig.map_bound(|sig| self.tcx.mk_fn_sig(
|
||||
iter::once(self.tcx.intern_tup(sig.inputs(), false)),
|
||||
sig.output(),
|
||||
sig.variadic,
|
||||
sig.unsafety,
|
||||
sig.abi
|
||||
));
|
||||
|
||||
debug!("closure for {:?} --> sig={:?} opt_kind={:?}",
|
||||
expr_def_id,
|
||||
fn_ty.sig,
|
||||
sig,
|
||||
opt_kind);
|
||||
|
||||
self.tables.borrow_mut().closure_tys.insert(expr.id, fn_ty);
|
||||
self.tables.borrow_mut().closure_tys.insert(expr.id, sig);
|
||||
match opt_kind {
|
||||
Some(kind) => {
|
||||
self.tables.borrow_mut().closure_kinds.insert(expr.id, kind);
|
||||
@ -228,7 +224,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let ret_param_ty = self.resolve_type_vars_if_possible(&ret_param_ty);
|
||||
debug!("deduce_sig_from_projection: ret_param_ty {:?}", ret_param_ty);
|
||||
|
||||
let fn_sig = self.tcx.mk_fn_sig(input_tys.cloned(), ret_param_ty, false);
|
||||
let fn_sig = self.tcx.mk_fn_sig(
|
||||
input_tys.cloned(),
|
||||
ret_param_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust
|
||||
);
|
||||
debug!("deduce_sig_from_projection: fn_sig {:?}", fn_sig);
|
||||
|
||||
Some(fn_sig)
|
||||
|
@ -507,11 +507,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
|
||||
fn coerce_from_safe_fn(&self,
|
||||
a: Ty<'tcx>,
|
||||
fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
|
||||
fn_ty_a: ty::PolyFnSig<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
if let ty::TyFnPtr(fn_ty_b) = b.sty {
|
||||
match (fn_ty_a.unsafety, fn_ty_b.unsafety) {
|
||||
match (fn_ty_a.unsafety(), fn_ty_b.unsafety()) {
|
||||
(hir::Unsafety::Normal, hir::Unsafety::Unsafe) => {
|
||||
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
|
||||
return self.unify_and_identity(unsafe_a, b)
|
||||
@ -525,7 +525,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
|
||||
fn coerce_from_fn_pointer(&self,
|
||||
a: Ty<'tcx>,
|
||||
fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
|
||||
fn_ty_a: ty::PolyFnSig<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
//! Attempts to coerce from the type of a Rust function item
|
||||
@ -540,7 +540,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
|
||||
fn coerce_from_fn_item(&self,
|
||||
a: Ty<'tcx>,
|
||||
fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
|
||||
fn_ty_a: ty::PolyFnSig<'tcx>,
|
||||
b: Ty<'tcx>)
|
||||
-> CoerceResult<'tcx> {
|
||||
//! Attempts to coerce from the type of a Rust function item
|
||||
@ -587,7 +587,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
// `extern "rust-call" fn((arg0,arg1,...)) -> _`
|
||||
// to
|
||||
// `fn(arg0,arg1,...) -> _`
|
||||
let sig = self.closure_type(def_id_a, substs_a).sig;
|
||||
let sig = self.closure_type(def_id_a, substs_a);
|
||||
let converted_sig = sig.map_bound(|s| {
|
||||
let params_iter = match s.inputs()[0].sty {
|
||||
ty::TyTuple(params, _) => {
|
||||
@ -595,16 +595,15 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
self.tcx.mk_fn_sig(params_iter,
|
||||
s.output(),
|
||||
s.variadic)
|
||||
self.tcx.mk_fn_sig(
|
||||
params_iter,
|
||||
s.output(),
|
||||
s.variadic,
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust
|
||||
)
|
||||
});
|
||||
let fn_ty = self.tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: abi::Abi::Rust,
|
||||
sig: converted_sig,
|
||||
});
|
||||
let pointer_ty = self.tcx.mk_fn_ptr(&fn_ty);
|
||||
let pointer_ty = self.tcx.mk_fn_ptr(converted_sig);
|
||||
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})",
|
||||
a, b, pointer_ty);
|
||||
self.unify_and_identity(pointer_ty, b)
|
||||
|
@ -263,19 +263,17 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// Compute skolemized form of impl and trait method tys.
|
||||
let tcx = infcx.tcx;
|
||||
|
||||
let m_fty = |method: &ty::AssociatedItem| {
|
||||
let m_sig = |method: &ty::AssociatedItem| {
|
||||
match tcx.item_type(method.def_id).sty {
|
||||
ty::TyFnDef(_, _, f) => f,
|
||||
_ => bug!()
|
||||
}
|
||||
};
|
||||
let impl_m_fty = m_fty(impl_m);
|
||||
let trait_m_fty = m_fty(trait_m);
|
||||
|
||||
let (impl_sig, _) =
|
||||
infcx.replace_late_bound_regions_with_fresh_var(impl_m_span,
|
||||
infer::HigherRankedType,
|
||||
&impl_m_fty.sig);
|
||||
&m_sig(impl_m));
|
||||
let impl_sig =
|
||||
impl_sig.subst(tcx, impl_to_skol_substs);
|
||||
let impl_sig =
|
||||
@ -284,16 +282,12 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl_m_span,
|
||||
impl_m_body_id,
|
||||
&impl_sig);
|
||||
let impl_fty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: impl_m_fty.unsafety,
|
||||
abi: impl_m_fty.abi,
|
||||
sig: ty::Binder(impl_sig.clone()),
|
||||
}));
|
||||
let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
|
||||
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
|
||||
|
||||
let trait_sig = tcx.liberate_late_bound_regions(
|
||||
infcx.parameter_environment.free_id_outlive,
|
||||
&trait_m_fty.sig);
|
||||
&m_sig(trait_m));
|
||||
let trait_sig =
|
||||
trait_sig.subst(tcx, trait_to_skol_substs);
|
||||
let trait_sig =
|
||||
@ -302,11 +296,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl_m_span,
|
||||
impl_m_body_id,
|
||||
&trait_sig);
|
||||
let trait_fty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: trait_m_fty.unsafety,
|
||||
abi: trait_m_fty.abi,
|
||||
sig: ty::Binder(trait_sig.clone()),
|
||||
}));
|
||||
let trait_fty = tcx.mk_fn_ptr(ty::Binder(trait_sig));
|
||||
|
||||
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
|
||||
|
||||
@ -662,8 +652,8 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
};
|
||||
let impl_m_fty = m_fty(impl_m);
|
||||
let trait_m_fty = m_fty(trait_m);
|
||||
let trait_number_args = trait_m_fty.sig.inputs().skip_binder().len();
|
||||
let impl_number_args = impl_m_fty.sig.inputs().skip_binder().len();
|
||||
let trait_number_args = trait_m_fty.inputs().skip_binder().len();
|
||||
let impl_number_args = impl_m_fty.inputs().skip_binder().len();
|
||||
if trait_number_args != impl_number_args {
|
||||
let trait_m_node_id = tcx.hir.as_local_node_id(trait_m.def_id);
|
||||
let trait_span = if let Some(trait_id) = trait_m_node_id {
|
||||
|
@ -123,8 +123,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
match method.def() {
|
||||
Def::Method(def_id) => {
|
||||
match self.tcx.item_type(def_id).sty {
|
||||
ty::TypeVariants::TyFnDef(_, _, fty) => {
|
||||
fty.sig.skip_binder().inputs().len() == 1
|
||||
ty::TypeVariants::TyFnDef(_, _, sig) => {
|
||||
sig.inputs().skip_binder().len() == 1
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -39,11 +39,13 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|_, _| tcx.mk_region(ty::ReErased),
|
||||
|def, _| tcx.mk_param_from_def(def));
|
||||
|
||||
let fty = tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
abi: abi,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(inputs.into_iter(), output, false)),
|
||||
}));
|
||||
let fty = tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
|
||||
inputs.into_iter(),
|
||||
output,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
abi
|
||||
)));
|
||||
let i_n_tps = tcx.item_generics(def_id).types.len();
|
||||
if i_n_tps != n_tps {
|
||||
let span = match it.node {
|
||||
@ -288,11 +290,13 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
"try" => {
|
||||
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
|
||||
let fn_ty = tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(iter::once(mut_u8), tcx.mk_nil(), false)),
|
||||
});
|
||||
let fn_ty = ty::Binder(tcx.mk_fn_sig(
|
||||
iter::once(mut_u8),
|
||||
tcx.mk_nil(),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust,
|
||||
));
|
||||
(0, vec![tcx.mk_fn_ptr(fn_ty), mut_u8, mut_u8], tcx.types.i32)
|
||||
}
|
||||
|
||||
@ -363,7 +367,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let mut structural_to_nomimal = FxHashMap();
|
||||
|
||||
let sig = tcx.item_type(def_id).fn_sig();
|
||||
let sig = tcx.no_late_bound_regions(sig).unwrap();
|
||||
let sig = tcx.no_late_bound_regions(&sig).unwrap();
|
||||
if intr.inputs.len() != sig.inputs().len() {
|
||||
span_err!(tcx.sess, it.span, E0444,
|
||||
"platform-specific intrinsic has invalid number of \
|
||||
|
@ -365,10 +365,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
debug!("method_predicates after subst = {:?}", method_predicates);
|
||||
|
||||
let fty = match self.tcx.item_type(def_id).sty {
|
||||
ty::TyFnDef(_, _, f) => f,
|
||||
_ => bug!()
|
||||
};
|
||||
let sig = self.tcx.item_type(def_id).fn_sig();
|
||||
|
||||
// Instantiate late-bound regions and substitute the trait
|
||||
// parameters into the method type to get the actual method type.
|
||||
@ -376,21 +373,15 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
// NB: Instantiate late-bound regions first so that
|
||||
// `instantiate_type_scheme` can normalize associated types that
|
||||
// may reference those regions.
|
||||
let method_sig = self.replace_late_bound_regions_with_fresh_var(&fty.sig);
|
||||
let method_sig = self.replace_late_bound_regions_with_fresh_var(&sig);
|
||||
debug!("late-bound lifetimes from method instantiated, method_sig={:?}",
|
||||
method_sig);
|
||||
|
||||
let method_sig = self.instantiate_type_scheme(self.span, all_substs, &method_sig);
|
||||
debug!("type scheme substituted, method_sig={:?}", method_sig);
|
||||
|
||||
let method_ty = self.tcx.mk_fn_def(def_id, all_substs,
|
||||
self.tcx.mk_bare_fn(ty::BareFnTy {
|
||||
sig: ty::Binder(method_sig),
|
||||
unsafety: fty.unsafety,
|
||||
abi: fty.abi,
|
||||
}));
|
||||
|
||||
(method_ty, method_predicates)
|
||||
(self.tcx.mk_fn_def(def_id, all_substs, ty::Binder(method_sig)),
|
||||
method_predicates)
|
||||
}
|
||||
|
||||
fn add_obligations(&mut self,
|
||||
|
@ -244,21 +244,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// `instantiate_type_scheme` can normalize associated types that
|
||||
// may reference those regions.
|
||||
let original_method_ty = tcx.item_type(def_id);
|
||||
let fty = match original_method_ty.sty {
|
||||
ty::TyFnDef(_, _, f) => f,
|
||||
_ => bug!()
|
||||
};
|
||||
let fn_sig = original_method_ty.fn_sig();
|
||||
let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
|
||||
infer::FnCall,
|
||||
&fty.sig).0;
|
||||
&fn_sig).0;
|
||||
let fn_sig = self.instantiate_type_scheme(span, trait_ref.substs, &fn_sig);
|
||||
let transformed_self_ty = fn_sig.inputs()[0];
|
||||
let method_ty = tcx.mk_fn_def(def_id, trait_ref.substs,
|
||||
tcx.mk_bare_fn(ty::BareFnTy {
|
||||
sig: ty::Binder(fn_sig),
|
||||
unsafety: fty.unsafety,
|
||||
abi: fty.abi
|
||||
}));
|
||||
ty::Binder(fn_sig));
|
||||
|
||||
debug!("lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
|
||||
method_ty,
|
||||
|
@ -675,25 +675,21 @@ fn check_bare_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
span: Span) {
|
||||
let body = tcx.hir.body(body_id);
|
||||
|
||||
let raw_fty = tcx.item_type(tcx.hir.local_def_id(fn_id));
|
||||
let fn_ty = match raw_fty.sty {
|
||||
ty::TyFnDef(.., f) => f,
|
||||
_ => span_bug!(body.value.span, "check_bare_fn: function type expected")
|
||||
};
|
||||
let fn_sig = tcx.item_type(tcx.hir.local_def_id(fn_id)).fn_sig();
|
||||
|
||||
check_abi(tcx, span, fn_ty.abi);
|
||||
check_abi(tcx, span, fn_sig.abi());
|
||||
|
||||
Inherited::build(tcx, fn_id).enter(|inh| {
|
||||
// Compute the fty from point of view of inside fn.
|
||||
let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body_id.node_id);
|
||||
let fn_sig =
|
||||
fn_ty.sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
||||
fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
||||
let fn_sig =
|
||||
inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
|
||||
let fn_sig =
|
||||
inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
|
||||
|
||||
let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body);
|
||||
let fcx = check_fn(&inh, fn_sig, decl, fn_id, body);
|
||||
|
||||
fcx.select_all_obligations_and_apply_defaults();
|
||||
fcx.closure_analyze(body);
|
||||
@ -783,9 +779,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
|
||||
/// * ...
|
||||
/// * inherited: other fields inherited from the enclosing fn (if any)
|
||||
fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
unsafety: hir::Unsafety,
|
||||
unsafety_id: ast::NodeId,
|
||||
fn_sig: &ty::FnSig<'tcx>,
|
||||
fn_sig: ty::FnSig<'tcx>,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
fn_id: ast::NodeId,
|
||||
body: &'gcx hir::Body)
|
||||
@ -799,12 +793,17 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
// in the case of function expressions, based on the outer context.
|
||||
let mut fcx = FnCtxt::new(inherited, None, body.value.id);
|
||||
let ret_ty = fn_sig.output();
|
||||
*fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id);
|
||||
*fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
|
||||
|
||||
fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
|
||||
fcx.ret_ty = fcx.instantiate_anon_types(&Some(ret_ty));
|
||||
fn_sig = fcx.tcx.mk_fn_sig(fn_sig.inputs().iter().cloned(), &fcx.ret_ty.unwrap(),
|
||||
fn_sig.variadic);
|
||||
fn_sig = fcx.tcx.mk_fn_sig(
|
||||
fn_sig.inputs().iter().cloned(),
|
||||
fcx.ret_ty.unwrap(),
|
||||
fn_sig.variadic,
|
||||
fn_sig.unsafety,
|
||||
fn_sig.abi
|
||||
);
|
||||
|
||||
GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
|
||||
|
||||
@ -2393,13 +2392,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let expected_arg_tys = self.expected_types_for_fn_args(
|
||||
sp,
|
||||
expected,
|
||||
fty.sig.0.output(),
|
||||
&fty.sig.0.inputs()[1..]
|
||||
fty.0.output(),
|
||||
&fty.0.inputs()[1..]
|
||||
);
|
||||
self.check_argument_types(sp, &fty.sig.0.inputs()[1..], &expected_arg_tys[..],
|
||||
args_no_rcvr, fty.sig.0.variadic, tuple_arguments,
|
||||
self.check_argument_types(sp, &fty.0.inputs()[1..], &expected_arg_tys[..],
|
||||
args_no_rcvr, fty.0.variadic, tuple_arguments,
|
||||
self.tcx.hir.span_if_local(def_id));
|
||||
fty.sig.0.output()
|
||||
fty.0.output()
|
||||
}
|
||||
_ => {
|
||||
span_bug!(callee_expr.span, "method without bare fn type");
|
||||
|
@ -927,7 +927,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
// was applied on the base type, as that is always the case.
|
||||
let fn_sig = method.ty.fn_sig();
|
||||
let fn_sig = // late-bound regions should have been instantiated
|
||||
self.tcx.no_late_bound_regions(fn_sig).unwrap();
|
||||
self.tcx.no_late_bound_regions(&fn_sig).unwrap();
|
||||
let self_ty = fn_sig.inputs()[0];
|
||||
let (m, r) = match self_ty.sty {
|
||||
ty::TyRef(r, ref m) => (m.mutbl, r),
|
||||
|
@ -182,11 +182,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let method_ty = fcx.tcx.item_type(item.def_id);
|
||||
let method_ty = fcx.instantiate_type_scheme(span, free_substs, &method_ty);
|
||||
let predicates = fcx.instantiate_bounds(span, item.def_id, free_substs);
|
||||
let fty = match method_ty.sty {
|
||||
ty::TyFnDef(_, _, f) => f,
|
||||
_ => bug!()
|
||||
};
|
||||
this.check_fn_or_method(fcx, span, fty, &predicates,
|
||||
let sig = method_ty.fn_sig();
|
||||
this.check_fn_or_method(fcx, span, sig, &predicates,
|
||||
free_id_outlive, &mut implied_bounds);
|
||||
let sig_if_method = sig_if_method.expect("bad signature for method");
|
||||
this.check_method_receiver(fcx, sig_if_method, &item,
|
||||
@ -339,18 +336,13 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
let def_id = fcx.tcx.hir.local_def_id(item.id);
|
||||
let ty = fcx.tcx.item_type(def_id);
|
||||
let item_ty = fcx.instantiate_type_scheme(item.span, free_substs, &ty);
|
||||
let bare_fn_ty = match item_ty.sty {
|
||||
ty::TyFnDef(.., ref bare_fn_ty) => bare_fn_ty,
|
||||
_ => {
|
||||
span_bug!(item.span, "Fn item without fn type");
|
||||
}
|
||||
};
|
||||
let sig = item_ty.fn_sig();
|
||||
|
||||
let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
|
||||
|
||||
let mut implied_bounds = vec![];
|
||||
let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id);
|
||||
this.check_fn_or_method(fcx, item.span, bare_fn_ty, &predicates,
|
||||
this.check_fn_or_method(fcx, item.span, sig, &predicates,
|
||||
free_id_outlive, &mut implied_bounds);
|
||||
implied_bounds
|
||||
})
|
||||
@ -435,14 +427,14 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
fn check_fn_or_method<'fcx, 'tcx>(&mut self,
|
||||
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
|
||||
span: Span,
|
||||
fty: &'tcx ty::BareFnTy<'tcx>,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
predicates: &ty::InstantiatedPredicates<'tcx>,
|
||||
free_id_outlive: CodeExtent,
|
||||
implied_bounds: &mut Vec<Ty<'tcx>>)
|
||||
{
|
||||
let free_substs = &fcx.parameter_environment.free_substs;
|
||||
let fty = fcx.instantiate_type_scheme(span, free_substs, &fty);
|
||||
let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);
|
||||
let sig = fcx.instantiate_type_scheme(span, free_substs, &sig);
|
||||
let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &sig);
|
||||
|
||||
for input_ty in sig.inputs() {
|
||||
fcx.register_wf_obligation(&input_ty, span, self.code.clone());
|
||||
|
@ -739,11 +739,13 @@ fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
CtorKind::Fn => {
|
||||
let inputs = variant.fields.iter().map(|field| tcx.item_type(field.did));
|
||||
let substs = mk_item_substs(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: abi::Abi::Rust,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(inputs, ty, false))
|
||||
}))
|
||||
tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
|
||||
inputs,
|
||||
ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust
|
||||
)))
|
||||
}
|
||||
};
|
||||
tcx.maps.ty.borrow_mut().insert(def_id, ctor_ty);
|
||||
@ -1682,11 +1684,11 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
|
||||
.emit();
|
||||
}
|
||||
};
|
||||
for (input, ty) in decl.inputs.iter().zip(*fty.sig.inputs().skip_binder()) {
|
||||
for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
|
||||
check(&input, ty)
|
||||
}
|
||||
if let hir::Return(ref ty) = decl.output {
|
||||
check(&ty, *fty.sig.output().skip_binder())
|
||||
check(&ty, *fty.output().skip_binder())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,11 +196,14 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
let substs = tcx.intern_substs(&[]);
|
||||
let se_ty = tcx.mk_fn_def(main_def_id, substs,
|
||||
tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(iter::empty(), tcx.mk_nil(), false))
|
||||
}));
|
||||
ty::Binder(tcx.mk_fn_sig(
|
||||
iter::empty(),
|
||||
tcx.mk_nil(),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust
|
||||
))
|
||||
);
|
||||
|
||||
require_same_types(
|
||||
tcx,
|
||||
@ -243,18 +246,17 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
let substs = tcx.intern_substs(&[]);
|
||||
let se_ty = tcx.mk_fn_def(start_def_id, substs,
|
||||
tcx.mk_bare_fn(ty::BareFnTy {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: Abi::Rust,
|
||||
sig: ty::Binder(tcx.mk_fn_sig(
|
||||
ty::Binder(tcx.mk_fn_sig(
|
||||
[
|
||||
tcx.types.isize,
|
||||
tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
|
||||
].iter().cloned(),
|
||||
tcx.types.isize,
|
||||
false,
|
||||
)),
|
||||
}));
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust
|
||||
))
|
||||
);
|
||||
|
||||
require_same_types(
|
||||
tcx,
|
||||
|
@ -411,8 +411,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::TyFnDef(.., &ty::BareFnTy { ref sig, .. }) |
|
||||
ty::TyFnPtr(&ty::BareFnTy { ref sig, .. }) => {
|
||||
ty::TyFnDef(.., sig) |
|
||||
ty::TyFnPtr(sig) => {
|
||||
self.add_constraints_from_sig(generics, sig, variance);
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
/// `sig` appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_sig(&mut self,
|
||||
generics: &ty::Generics,
|
||||
sig: &ty::PolyFnSig<'tcx>,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
let contra = self.contravariant(variance);
|
||||
for &input in sig.0.inputs() {
|
||||
|
@ -164,11 +164,7 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
|
||||
}
|
||||
|
||||
fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
|
||||
let ty = cx.tcx.item_type(did);
|
||||
let (decl, style, abi) = match ty.sty {
|
||||
ty::TyFnDef(.., ref f) => ((did, &f.sig).clean(cx), f.unsafety, f.abi),
|
||||
_ => panic!("bad function"),
|
||||
};
|
||||
let sig = cx.tcx.item_type(did).fn_sig();
|
||||
|
||||
let constness = if cx.tcx.sess.cstore.is_const_fn(did) {
|
||||
hir::Constness::Const
|
||||
@ -178,11 +174,11 @@ fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
|
||||
|
||||
let predicates = cx.tcx.item_predicates(did);
|
||||
clean::Function {
|
||||
decl: decl,
|
||||
decl: (did, sig).clean(cx),
|
||||
generics: (cx.tcx.item_generics(did), &predicates).clean(cx),
|
||||
unsafety: style,
|
||||
unsafety: sig.unsafety(),
|
||||
constness: constness,
|
||||
abi: abi,
|
||||
abi: sig.abi(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1163,7 +1163,7 @@ impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl, A)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
|
||||
impl<'a, 'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
|
||||
fn clean(&self, cx: &DocContext) -> FnDecl {
|
||||
let (did, sig) = *self;
|
||||
let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() {
|
||||
@ -1352,11 +1352,8 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||
ty::AssociatedKind::Method => {
|
||||
let generics = (cx.tcx.item_generics(self.def_id),
|
||||
&cx.tcx.item_predicates(self.def_id)).clean(cx);
|
||||
let fty = match cx.tcx.item_type(self.def_id).sty {
|
||||
ty::TyFnDef(_, _, f) => f,
|
||||
_ => unreachable!()
|
||||
};
|
||||
let mut decl = (self.def_id, &fty.sig).clean(cx);
|
||||
let sig = cx.tcx.item_type(self.def_id).fn_sig();
|
||||
let mut decl = (self.def_id, sig).clean(cx);
|
||||
|
||||
if self.method_has_self_argument {
|
||||
let self_ty = match self.container {
|
||||
@ -1365,7 +1362,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||
}
|
||||
ty::TraitContainer(_) => cx.tcx.mk_self_type()
|
||||
};
|
||||
let self_arg_ty = *fty.sig.input(0).skip_binder();
|
||||
let self_arg_ty = *sig.input(0).skip_binder();
|
||||
if self_arg_ty == self_ty {
|
||||
decl.inputs.values[0].type_ = Generic(String::from("Self"));
|
||||
} else if let ty::TyRef(_, mt) = self_arg_ty.sty {
|
||||
@ -1386,20 +1383,20 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||
};
|
||||
if provided {
|
||||
MethodItem(Method {
|
||||
unsafety: fty.unsafety,
|
||||
unsafety: sig.unsafety(),
|
||||
generics: generics,
|
||||
decl: decl,
|
||||
abi: fty.abi,
|
||||
abi: sig.abi(),
|
||||
|
||||
// trait methods canot (currently, at least) be const
|
||||
constness: hir::Constness::NotConst,
|
||||
})
|
||||
} else {
|
||||
TyMethodItem(TyMethod {
|
||||
unsafety: fty.unsafety,
|
||||
unsafety: sig.unsafety(),
|
||||
generics: generics,
|
||||
decl: decl,
|
||||
abi: fty.abi,
|
||||
abi: sig.abi(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1834,16 +1831,16 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
mutability: mt.mutbl.clean(cx),
|
||||
type_: box mt.ty.clean(cx),
|
||||
},
|
||||
ty::TyFnDef(.., ref fty) |
|
||||
ty::TyFnPtr(ref fty) => BareFunction(box BareFunctionDecl {
|
||||
unsafety: fty.unsafety,
|
||||
ty::TyFnDef(.., sig) |
|
||||
ty::TyFnPtr(sig) => BareFunction(box BareFunctionDecl {
|
||||
unsafety: sig.unsafety(),
|
||||
generics: Generics {
|
||||
lifetimes: Vec::new(),
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), &fty.sig).clean(cx),
|
||||
abi: fty.abi,
|
||||
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
|
||||
abi: sig.abi(),
|
||||
}),
|
||||
ty::TyAdt(def, substs) => {
|
||||
let did = def.did;
|
||||
|
Loading…
Reference in New Issue
Block a user