Ty<'gcx>,
&'gcx Substs<'gcx>,
ty::FnSig<'gcx>,
- &'gcx ty::BareFnTy<'gcx>,
+ ty::PolyFnSig<'gcx>,
ty::ClosureSubsts<'gcx>,
ty::PolyTraitRef<'gcx>,
ty::ExistentialTraitRef<'gcx>
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) {
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,
}
}
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"
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);
}
_ => {
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()
};
confirm_callable_candidate(selcx,
obligation,
- &closure_type.sig,
+ closure_type,
util::TupleArgumentsFlag::No)
.with_addl_obligations(vtable.nested)
.with_addl_obligations(obligations)
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>
{
}
// 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);
}
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
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>)>
{
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};
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};
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>>>>>,
}
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()),
}
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>,
}
}
-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};
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());
}
}
-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
}
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,
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
}))
}
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))
}
}
}
- 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
})
}
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 {
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);
}
}
}
}
}
- 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());
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)
}
/// 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)
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};
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);
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>,
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);
}).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
})
}
}
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,
}
})
}
}
}
-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 }
ty::FnSig {
inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
variadic: self.variadic,
+ unsafety: self.unsafety,
+ abi: self.abi,
}
}
/// 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),
/// 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]
}
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>> {
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)]
}
}
- 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()
}
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() {
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());
}
}
}
-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({:?},{:?})",
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())
}
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]"),
{
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" {
}
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> {
}
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));
}
_ => (),
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"
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 \
_ => {}
}
- 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 {
}
}
-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)?;
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!(),
#[derive(RustcEncodable, RustcDecodable)]
pub struct ClosureData<'tcx> {
pub kind: ty::ClosureKind,
- pub ty: Lazy<ty::ClosureTy<'tcx>>,
+ pub ty: Lazy<ty::PolyFnSig<'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
};
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);
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);
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))
}
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);
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,
};
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 {
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
};
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 ||
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;
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,
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>,
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() {
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
/// 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
}
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());
// 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);
//
// 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) {
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"
}
}
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.
use rustc::hir;
use libc::{c_uint, c_char};
-use std::borrow::Cow;
use std::iter;
use syntax::ast;
}
}
-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) {
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)
}
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);
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);
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()
/// 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 {
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)
};
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), &[]);
}
_ => 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()
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));
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());
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);
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
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);
}
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();
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);
// 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));
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
// 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) {
.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)
use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos, Span};
use syntax::symbol::keywords;
-use syntax::abi::Abi;
use std::iter;
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);
.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(
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());
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());
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() {
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(..) => {
// 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 {
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> =
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,
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);
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
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;
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 {
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 {
// 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)
}
};
// 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);
// (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);
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
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);
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)
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)
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
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
// `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, _) => {
}
_ => 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)
// 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 =
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 =
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);
};
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 {
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,
}
|_, _| 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 {
"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)
}
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 \
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.
// 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,
// `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,
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);
/// * ...
/// * 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)
// 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);
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");
// 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),
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,
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
})
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());
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);
.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())
}
}
}
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,
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,
}
}
- 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);
}
/// `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() {
}
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
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(),
}
}
}
}
-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() {
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 {
}
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 {
};
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(),
})
}
}
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;