rustc: move the PolyFnSig out of TyFnDef.

This commit is contained in:
Eduard-Mihai Burtescu 2017-05-13 17:11:52 +03:00
parent 8e53a03d15
commit 33ecf72e8e
61 changed files with 427 additions and 354 deletions

View File

@ -524,10 +524,9 @@ for ty::TypeVariants<'tcx>
region.hash_stable(hcx, hasher); region.hash_stable(hcx, hasher);
pointee_ty.hash_stable(hcx, hasher); pointee_ty.hash_stable(hcx, hasher);
} }
TyFnDef(def_id, substs, ref sig) => { TyFnDef(def_id, substs) => {
def_id.hash_stable(hcx, hasher); def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher);
sig.hash_stable(hcx, hasher);
} }
TyFnPtr(ref sig) => { TyFnPtr(ref sig) => {
sig.hash_stable(hcx, hasher); sig.hash_stable(hcx, hasher);

View File

@ -12,7 +12,7 @@
//! `unsafe`. //! `unsafe`.
use self::RootUnsafeContext::*; use self::RootUnsafeContext::*;
use ty::{self, Ty, TyCtxt}; use ty::{self, TyCtxt};
use lint; use lint;
use syntax::ast; use syntax::ast;
@ -40,14 +40,6 @@ enum RootUnsafeContext {
UnsafeBlock(ast::NodeId), UnsafeBlock(ast::NodeId),
} }
fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::TyFnDef(.., f) |
ty::TyFnPtr(f) => f.unsafety() == hir::Unsafety::Unsafe,
_ => false,
}
}
struct EffectCheckVisitor<'a, 'tcx: 'a> { struct EffectCheckVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>, tables: &'a ty::TypeckTables<'tcx>,
@ -174,10 +166,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
match expr.node { match expr.node {
hir::ExprMethodCall(..) => { hir::ExprMethodCall(..) => {
let def_id = self.tables.type_dependent_defs[&expr.id].def_id(); let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
let base_type = self.tcx.type_of(def_id); let sig = self.tcx.fn_sig(def_id);
debug!("effect: method call case, base type is {:?}", debug!("effect: method call case, signature is {:?}",
base_type); sig);
if type_is_unsafe_function(base_type) {
if sig.0.unsafety == hir::Unsafety::Unsafe {
self.require_unsafe(expr.span, self.require_unsafe(expr.span,
"invocation of unsafe method") "invocation of unsafe method")
} }
@ -186,8 +179,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
let base_type = self.tables.expr_ty_adjusted(base); let base_type = self.tables.expr_ty_adjusted(base);
debug!("effect: call case, base type is {:?}", debug!("effect: call case, base type is {:?}",
base_type); base_type);
if type_is_unsafe_function(base_type) { match base_type.sty {
self.require_unsafe(expr.span, "call to unsafe function") ty::TyFnDef(..) | ty::TyFnPtr(_) => {
if base_type.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
self.require_unsafe(expr.span, "call to unsafe function")
}
}
_ => {}
} }
} }
hir::ExprUnary(hir::UnDeref, ref base) => { hir::ExprUnary(hir::UnDeref, ref base) => {

View File

@ -66,11 +66,8 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl<'a, 'tcx> ExprVisitor<'a, 'tcx> { impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool { fn def_id_is_transmute(&self, def_id: DefId) -> bool {
let intrinsic = match self.tcx.type_of(def_id).sty { self.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic, self.tcx.item_name(def_id) == "transmute"
_ => return false
};
intrinsic && self.tcx.item_name(def_id) == "transmute"
} }
fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
@ -153,22 +150,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
} else { } else {
Def::Err Def::Err
}; };
match def { if let Def::Fn(did) = def {
Def::Fn(did) if self.def_id_is_transmute(did) => { if self.def_id_is_transmute(did) {
let typ = self.tables.node_id_to_type(expr.id); let typ = self.tables.node_id_to_type(expr.id);
let typ = self.tcx.lift_to_global(&typ).unwrap(); let sig = typ.fn_sig(self.tcx);
match typ.sty { let from = sig.inputs().skip_binder()[0];
ty::TyFnDef(.., sig) if sig.abi() == RustIntrinsic => { let to = *sig.output().skip_binder();
let from = sig.inputs().skip_binder()[0]; self.check_transmute(expr.span, from, to);
let to = *sig.output().skip_binder();
self.check_transmute(expr.span, from, to);
}
_ => {
span_bug!(expr.span, "transmute wasn't a bare fn?!");
}
}
} }
_ => {}
} }
intravisit::walk_expr(self, expr); intravisit::walk_expr(self, expr);

View File

@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// The `Self` type is erased, so it should not appear in list of // The `Self` type is erased, so it should not appear in list of
// arguments or return type apart from the receiver. // arguments or return type apart from the receiver.
let ref sig = self.type_of(method.def_id).fn_sig(); let ref sig = self.fn_sig(method.def_id);
for input_ty in &sig.skip_binder().inputs()[1..] { for input_ty in &sig.skip_binder().inputs()[1..] {
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) { if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
return Some(MethodViolationCode::ReferencesSelf); return Some(MethodViolationCode::ReferencesSelf);

View File

@ -1137,9 +1137,19 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
-> Progress<'tcx> -> Progress<'tcx>
{ {
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty); let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
let sig = fn_type.fn_sig(); let sig = fn_type.fn_sig(selcx.tcx());
let Normalized {
value: sig,
obligations
} = normalize_with_depth(selcx,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth+1,
&sig);
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes) confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
.with_addl_obligations(fn_pointer_vtable.nested) .with_addl_obligations(fn_pointer_vtable.nested)
.with_addl_obligations(obligations)
} }
fn confirm_closure_candidate<'cx, 'gcx, 'tcx>( fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(

View File

@ -1404,19 +1404,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
} }
// provide an impl, but only for suitable `fn` pointers // provide an impl, but only for suitable `fn` pointers
ty::TyFnDef(.., ty::Binder(ty::FnSig { ty::TyFnDef(..) | ty::TyFnPtr(_) => {
unsafety: hir::Unsafety::Normal, if let ty::Binder(ty::FnSig {
abi: Abi::Rust, unsafety: hir::Unsafety::Normal,
variadic: false, abi: Abi::Rust,
.. variadic: false,
})) | ..
ty::TyFnPtr(ty::Binder(ty::FnSig { }) = self_ty.fn_sig(self.tcx()) {
unsafety: hir::Unsafety::Normal, candidates.vec.push(FnPointerCandidate);
abi: Abi::Rust, }
variadic: false,
..
})) => {
candidates.vec.push(FnPointerCandidate);
} }
_ => { } _ => { }
@ -2348,7 +2344,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// ok to skip binder; it is reintroduced below // ok to skip binder; it is reintroduced below
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
let sig = self_ty.fn_sig(); let sig = self_ty.fn_sig(self.tcx());
let trait_ref = let trait_ref =
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(), self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
self_ty, self_ty,
@ -2356,11 +2352,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
util::TupleArgumentsFlag::Yes) util::TupleArgumentsFlag::Yes)
.map_bound(|(trait_ref, _)| trait_ref); .map_bound(|(trait_ref, _)| trait_ref);
let Normalized { value: trait_ref, obligations } =
project::normalize_with_depth(self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
&trait_ref);
self.confirm_poly_trait_refs(obligation.cause.clone(), self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env, obligation.param_env,
obligation.predicate.to_poly_trait_ref(), obligation.predicate.to_poly_trait_ref(),
trait_ref)?; trait_ref)?;
Ok(VtableFnPointerData { fn_ty: self_ty, nested: vec![] }) Ok(VtableFnPointerData { fn_ty: self_ty, nested: obligations })
} }
fn confirm_closure_candidate(&mut self, fn confirm_closure_candidate(&mut self,

View File

@ -1378,9 +1378,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
} }
pub fn mk_fn_def(self, def_id: DefId, pub fn mk_fn_def(self, def_id: DefId,
substs: &'tcx Substs<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
fty: PolyFnSig<'tcx>) -> Ty<'tcx> { self.mk_ty(TyFnDef(def_id, substs))
self.mk_ty(TyFnDef(def_id, substs, fty))
} }
pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> { pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {

View File

@ -68,6 +68,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
// view of possibly unifying // view of possibly unifying
simplify_type(tcx, mt.ty, can_simplify_params) simplify_type(tcx, mt.ty, can_simplify_params)
} }
ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) => { ty::TyClosure(def_id, _) => {
Some(ClosureSimplifiedType(def_id)) Some(ClosureSimplifiedType(def_id))
} }
@ -75,7 +76,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty::TyTuple(ref tys, _) => { ty::TyTuple(ref tys, _) => {
Some(TupleSimplifiedType(tys.len())) Some(TupleSimplifiedType(tys.len()))
} }
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => { ty::TyFnPtr(ref f) => {
Some(FunctionSimplifiedType(f.skip_binder().inputs().len())) Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
} }
ty::TyProjection(_) | ty::TyParam(_) => { ty::TyProjection(_) | ty::TyParam(_) => {

View File

@ -155,9 +155,8 @@ impl FlagComputation {
self.add_tys(&ts[..]); self.add_tys(&ts[..]);
} }
&ty::TyFnDef(_, substs, f) => { &ty::TyFnDef(_, substs) => {
self.add_substs(substs); self.add_substs(substs);
self.add_fn_sig(f);
} }
&ty::TyFnPtr(f) => { &ty::TyFnPtr(f) => {

View File

@ -348,7 +348,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
.filter_map(|ty| characteristic_def_id_of_type(ty)) .filter_map(|ty| characteristic_def_id_of_type(ty))
.next(), .next(),
ty::TyFnDef(def_id, ..) | ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) => Some(def_id), ty::TyClosure(def_id, _) => Some(def_id),
ty::TyBool | ty::TyBool |

View File

@ -206,7 +206,7 @@ impl AssociatedItem {
// late-bound regions, and we don't want method signatures to show up // late-bound regions, and we don't want method signatures to show up
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
// regions just fine, showing `fn(&MyType)`. // regions just fine, showing `fn(&MyType)`.
format!("{}", tcx.type_of(self.def_id).fn_sig().skip_binder()) format!("{}", tcx.fn_sig(self.def_id).skip_binder())
} }
ty::AssociatedKind::Type => format!("type {};", self.name.to_string()), ty::AssociatedKind::Type => format!("type {};", self.name.to_string()),
ty::AssociatedKind::Const => { ty::AssociatedKind::Const => {

View File

@ -440,13 +440,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
} }
} }
(&ty::TyFnDef(a_def_id, a_substs, a_fty), (&ty::TyFnDef(a_def_id, a_substs), &ty::TyFnDef(b_def_id, b_substs))
&ty::TyFnDef(b_def_id, b_substs, b_fty))
if a_def_id == b_def_id => if a_def_id == b_def_id =>
{ {
let substs = relate_substs(relation, None, a_substs, b_substs)?; let substs = relate_substs(relation, None, a_substs, b_substs)?;
let fty = relation.relate(&a_fty, &b_fty)?; Ok(tcx.mk_fn_def(a_def_id, substs))
Ok(tcx.mk_fn_def(a_def_id, substs, fty))
} }
(&ty::TyFnPtr(a_fty), &ty::TyFnPtr(b_fty)) => (&ty::TyFnPtr(a_fty), &ty::TyFnPtr(b_fty)) =>

View File

@ -531,10 +531,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyDynamic(ref trait_ty, ref region) => ty::TyDynamic(ref trait_ty, ref region) =>
ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)), ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted), ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
ty::TyFnDef(def_id, substs, f) => { ty::TyFnDef(def_id, substs) => {
ty::TyFnDef(def_id, ty::TyFnDef(def_id, substs.fold_with(folder))
substs.fold_with(folder),
f.fold_with(folder))
} }
ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)), ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
ty::TyRef(ref r, tm) => { ty::TyRef(ref r, tm) => {
@ -568,9 +566,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyDynamic(ref trait_ty, ref reg) => ty::TyDynamic(ref trait_ty, ref reg) =>
trait_ty.visit_with(visitor) || reg.visit_with(visitor), trait_ty.visit_with(visitor) || reg.visit_with(visitor),
ty::TyTuple(ts, _) => ts.visit_with(visitor), ty::TyTuple(ts, _) => ts.visit_with(visitor),
ty::TyFnDef(_, substs, ref f) => { ty::TyFnDef(_, substs) => substs.visit_with(visitor),
substs.visit_with(visitor) || f.visit_with(visitor)
}
ty::TyFnPtr(ref f) => f.visit_with(visitor), ty::TyFnPtr(ref f) => f.visit_with(visitor),
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor), ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor), ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),

View File

@ -14,7 +14,7 @@ use hir::def_id::DefId;
use hir::map::DefPathHash; use hir::map::DefPathHash;
use middle::region; use middle::region;
use ty::subst::Substs; use ty::subst::{Substs, Subst};
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
use ty::{Slice, TyS}; use ty::{Slice, TyS};
use ty::subst::Kind; use ty::subst::Kind;
@ -138,7 +138,7 @@ pub enum TypeVariants<'tcx> {
/// The anonymous type of a function declaration/definition. Each /// The anonymous type of a function declaration/definition. Each
/// function has a unique type. /// function has a unique type.
TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>), TyFnDef(DefId, &'tcx Substs<'tcx>),
/// A pointer to a function. Written as `fn() -> i32`. /// A pointer to a function. Written as `fn() -> i32`.
TyFnPtr(PolyFnSig<'tcx>), TyFnPtr(PolyFnSig<'tcx>),
@ -1329,9 +1329,12 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
} }
} }
pub fn fn_sig(&self) -> PolyFnSig<'tcx> { pub fn fn_sig(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PolyFnSig<'tcx> {
match self.sty { match self.sty {
TyFnDef(.., f) | TyFnPtr(f) => f, TyFnDef(def_id, substs) => {
tcx.fn_sig(def_id).subst(tcx, substs)
}
TyFnPtr(f) => f,
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self) _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
} }
} }

View File

@ -679,7 +679,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
TyRef(_, m) => self.hash(m.mutbl), TyRef(_, m) => self.hash(m.mutbl),
TyClosure(def_id, _) | TyClosure(def_id, _) |
TyAnon(def_id, _) | TyAnon(def_id, _) |
TyFnDef(def_id, ..) => self.def_id(def_id), TyFnDef(def_id, _) => self.def_id(def_id),
TyAdt(d, _) => self.def_id(d.did), TyAdt(d, _) => self.def_id(d.did),
TyFnPtr(f) => { TyFnPtr(f) => {
self.hash(f.unsafety()); self.hash(f.unsafety());

View File

@ -115,9 +115,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
ty::TyTuple(ts, _) => { ty::TyTuple(ts, _) => {
stack.extend(ts.iter().cloned().rev()); stack.extend(ts.iter().cloned().rev());
} }
ty::TyFnDef(_, substs, ft) => { ty::TyFnDef(_, substs) => {
stack.extend(substs.types().rev()); stack.extend(substs.types().rev());
push_sig_subtypes(stack, ft);
} }
ty::TyFnPtr(ft) => { ty::TyFnPtr(ft) => {
push_sig_subtypes(stack, ft); push_sig_subtypes(stack, ft);

View File

@ -753,8 +753,14 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
} }
write!(f, ")") write!(f, ")")
} }
TyFnDef(def_id, substs, ref bare_fn) => { TyFnDef(def_id, substs) => {
write!(f, "{} {{", bare_fn.0)?; ty::tls::with(|tcx| {
let mut sig = tcx.fn_sig(def_id);
if let Some(substs) = tcx.lift(&substs) {
sig = sig.subst(tcx, substs);
}
write!(f, "{} {{", sig.0)
})?;
parameterized(f, substs, def_id, &[])?; parameterized(f, substs, def_id, &[])?;
write!(f, "}}") write!(f, "}}")
} }

View File

@ -161,18 +161,13 @@ fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
terminator: &'a Option<mir::Terminator<'tcx>>) terminator: &'a Option<mir::Terminator<'tcx>>)
-> Option<(&'a [mir::Operand<'tcx>], Span)> { -> Option<(&'a [mir::Operand<'tcx>], Span)> {
if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator { if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind {
{ if let mir::Operand::Constant(ref func) = *oper {
if let mir::Operand::Constant(ref func) = *oper if let ty::TyFnDef(def_id, _) = func.ty.sty {
{ let abi = tcx.fn_sig(def_id).abi();
if let ty::TyFnDef(def_id, _, sig) = func.ty.sty
{
let abi = sig.abi();
let name = tcx.item_name(def_id); let name = tcx.item_name(def_id);
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic { if abi == Abi::RustIntrinsic && name == "rustc_peek" {
if name == "rustc_peek" { return Some((args, source_info.span));
return Some((args, source_info.span));
}
} }
} }
} }

View File

@ -12,7 +12,7 @@ use eval;
use rustc::middle::const_val::{ConstEvalErr, ConstVal}; use rustc::middle::const_val::{ConstEvalErr, ConstVal};
use rustc::mir::{Field, BorrowKind, Mutability}; use rustc::mir::{Field, BorrowKind, Mutability};
use rustc::ty::{self, TyCtxt, AdtDef, Ty, TypeVariants, Region}; use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region};
use rustc::ty::subst::{Substs, Kind}; use rustc::ty::subst::{Substs, Kind};
use rustc::hir::{self, PatKind, RangeEnd}; use rustc::hir::{self, PatKind, RangeEnd};
use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def::{Def, CtorKind};
@ -549,8 +549,8 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> {
let adt_def = self.tcx.adt_def(enum_id); let adt_def = self.tcx.adt_def(enum_id);
if adt_def.variants.len() > 1 { if adt_def.variants.len() > 1 {
let substs = match ty.sty { let substs = match ty.sty {
TypeVariants::TyAdt(_, substs) => substs, ty::TyAdt(_, substs) |
TypeVariants::TyFnDef(_, substs, _) => substs, ty::TyFnDef(_, substs) => substs,
_ => bug!("inappropriate type for def: {:?}", ty.sty), _ => bug!("inappropriate type for def: {:?}", ty.sty),
}; };
PatternKind::Variant { PatternKind::Variant {

View File

@ -1154,24 +1154,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
if !def_id_is_transmute(cx, did) { if !def_id_is_transmute(cx, did) {
return None; return None;
} }
let typ = cx.tables.node_id_to_type(expr.id); let sig = cx.tables.node_id_to_type(expr.id).fn_sig(cx.tcx);
match typ.sty { let from = sig.inputs().skip_binder()[0];
ty::TyFnDef(.., bare_fn) if bare_fn.abi() == RustIntrinsic => { let to = *sig.output().skip_binder();
let from = bare_fn.inputs().skip_binder()[0]; return Some((&from.sty, &to.sty));
let to = *bare_fn.output().skip_binder();
return Some((&from.sty, &to.sty));
}
_ => (),
}
} }
None None
} }
fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool { fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool {
match cx.tcx.type_of(def_id).sty { cx.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
ty::TyFnDef(.., bfty) if bfty.abi() == RustIntrinsic => (),
_ => return false,
}
cx.tcx.item_name(def_id) == "transmute" cx.tcx.item_name(def_id) == "transmute"
} }
} }

View File

@ -659,7 +659,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) { fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
let def_id = self.cx.tcx.hir.local_def_id(id); let def_id = self.cx.tcx.hir.local_def_id(id);
let sig = self.cx.tcx.type_of(def_id).fn_sig(); let sig = self.cx.tcx.fn_sig(def_id);
let sig = self.cx.tcx.erase_late_bound_regions(&sig); let sig = self.cx.tcx.erase_late_bound_regions(&sig);
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) { for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {

View File

@ -1085,13 +1085,19 @@ impl<'a, 'tcx> CrateMetadata {
} }
pub fn fn_sig(&self, pub fn fn_sig(&self,
closure_id: DefIndex, id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>) tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::PolyFnSig<'tcx> { -> ty::PolyFnSig<'tcx> {
match self.entry(closure_id).kind { let sig = match self.entry(id).kind {
EntryKind::Closure(data) => data.decode(self).sig.decode((self, tcx)), EntryKind::Fn(data) |
EntryKind::ForeignFn(data) => data.decode(self).sig,
EntryKind::Method(data) => data.decode(self).fn_data.sig,
EntryKind::Variant(data) |
EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(),
EntryKind::Closure(data) => data.decode(self).sig,
_ => bug!(), _ => bug!(),
} };
sig.decode((self, tcx))
} }
#[inline] #[inline]

View File

@ -16,6 +16,7 @@ use schema::*;
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary, use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
EncodedMetadata, EncodedMetadataHashes, EncodedMetadata, EncodedMetadataHashes,
EncodedMetadataHash}; EncodedMetadataHash};
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind}; use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::ich::Fingerprint; use rustc::ich::Fingerprint;
@ -499,6 +500,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
struct_ctor: None, struct_ctor: None,
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
Some(self.lazy(&tcx.fn_sig(def_id)))
} else {
None
}
}; };
let enum_id = tcx.hir.as_local_node_id(enum_did).unwrap(); let enum_id = tcx.hir.as_local_node_id(enum_did).unwrap();
@ -617,6 +623,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
struct_ctor: Some(def_id.index), struct_ctor: Some(def_id.index),
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
Some(self.lazy(&tcx.fn_sig(def_id)))
} else {
None
}
}; };
let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap(); let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap();
@ -695,7 +706,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
}; };
FnData { FnData {
constness: hir::Constness::NotConst, constness: hir::Constness::NotConst,
arg_names: arg_names arg_names: arg_names,
sig: self.lazy(&tcx.fn_sig(def_id)),
} }
} else { } else {
bug!() bug!()
@ -747,6 +759,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> { fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id); debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id);
let tcx = self.tcx;
let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
let ast_item = self.tcx.hir.expect_impl_item(node_id); let ast_item = self.tcx.hir.expect_impl_item(node_id);
let impl_item = self.tcx.associated_item(def_id); let impl_item = self.tcx.associated_item(def_id);
@ -768,6 +782,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
FnData { FnData {
constness: sig.constness, constness: sig.constness,
arg_names: self.encode_fn_arg_names_for_body(body), arg_names: self.encode_fn_arg_names_for_body(body),
sig: self.lazy(&tcx.fn_sig(def_id)),
} }
} else { } else {
bug!() bug!()
@ -881,6 +896,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
let data = FnData { let data = FnData {
constness: constness, constness: constness,
arg_names: self.encode_fn_arg_names_for_body(body), arg_names: self.encode_fn_arg_names_for_body(body),
sig: self.lazy(&tcx.fn_sig(def_id)),
}; };
EntryKind::Fn(self.lazy(&data)) EntryKind::Fn(self.lazy(&data))
@ -910,6 +926,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
struct_ctor: struct_ctor, struct_ctor: struct_ctor,
ctor_sig: None,
}), repr_options) }), repr_options)
} }
hir::ItemUnion(..) => { hir::ItemUnion(..) => {
@ -920,6 +937,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind, ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
struct_ctor: None, struct_ctor: None,
ctor_sig: None,
}), repr_options) }), repr_options)
} }
hir::ItemDefaultImpl(..) => { hir::ItemDefaultImpl(..) => {
@ -1363,6 +1381,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
let data = FnData { let data = FnData {
constness: hir::Constness::NotConst, constness: hir::Constness::NotConst,
arg_names: self.encode_fn_arg_names(names), arg_names: self.encode_fn_arg_names(names),
sig: self.lazy(&tcx.fn_sig(def_id)),
}; };
EntryKind::ForeignFn(self.lazy(&data)) EntryKind::ForeignFn(self.lazy(&data))
} }

View File

@ -343,18 +343,18 @@ pub enum EntryKind<'tcx> {
Type, Type,
Enum(ReprOptions), Enum(ReprOptions),
Field, Field,
Variant(Lazy<VariantData>), Variant(Lazy<VariantData<'tcx>>),
Struct(Lazy<VariantData>, ReprOptions), Struct(Lazy<VariantData<'tcx>>, ReprOptions),
Union(Lazy<VariantData>, ReprOptions), Union(Lazy<VariantData<'tcx>>, ReprOptions),
Fn(Lazy<FnData>), Fn(Lazy<FnData<'tcx>>),
ForeignFn(Lazy<FnData>), ForeignFn(Lazy<FnData<'tcx>>),
Mod(Lazy<ModData>), Mod(Lazy<ModData>),
MacroDef(Lazy<MacroDef>), MacroDef(Lazy<MacroDef>),
Closure(Lazy<ClosureData<'tcx>>), Closure(Lazy<ClosureData<'tcx>>),
Trait(Lazy<TraitData<'tcx>>), Trait(Lazy<TraitData<'tcx>>),
Impl(Lazy<ImplData<'tcx>>), Impl(Lazy<ImplData<'tcx>>),
DefaultImpl(Lazy<ImplData<'tcx>>), DefaultImpl(Lazy<ImplData<'tcx>>),
Method(Lazy<MethodData>), Method(Lazy<MethodData<'tcx>>),
AssociatedType(AssociatedContainer), AssociatedType(AssociatedContainer),
AssociatedConst(AssociatedContainer, u8), AssociatedConst(AssociatedContainer, u8),
} }
@ -439,27 +439,33 @@ pub struct MacroDef {
impl_stable_hash_for!(struct MacroDef { body, legacy }); impl_stable_hash_for!(struct MacroDef { body, legacy });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct FnData { pub struct FnData<'tcx> {
pub constness: hir::Constness, pub constness: hir::Constness,
pub arg_names: LazySeq<ast::Name>, pub arg_names: LazySeq<ast::Name>,
pub sig: Lazy<ty::PolyFnSig<'tcx>>,
} }
impl_stable_hash_for!(struct FnData { constness, arg_names }); impl_stable_hash_for!(struct FnData<'tcx> { constness, arg_names, sig });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct VariantData { pub struct VariantData<'tcx> {
pub ctor_kind: CtorKind, pub ctor_kind: CtorKind,
pub discr: ty::VariantDiscr, pub discr: ty::VariantDiscr,
/// If this is a struct's only variant, this /// If this is a struct's only variant, this
/// is the index of the "struct ctor" item. /// is the index of the "struct ctor" item.
pub struct_ctor: Option<DefIndex>, pub struct_ctor: Option<DefIndex>,
/// If this is a tuple struct or variant
/// ctor, this is its "function" signature.
pub ctor_sig: Option<Lazy<ty::PolyFnSig<'tcx>>>,
} }
impl_stable_hash_for!(struct VariantData { impl_stable_hash_for!(struct VariantData<'tcx> {
ctor_kind, ctor_kind,
discr, discr,
struct_ctor struct_ctor,
ctor_sig
}); });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
@ -543,12 +549,12 @@ impl AssociatedContainer {
} }
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct MethodData { pub struct MethodData<'tcx> {
pub fn_data: FnData, pub fn_data: FnData<'tcx>,
pub container: AssociatedContainer, pub container: AssociatedContainer,
pub has_self: bool, pub has_self: bool,
} }
impl_stable_hash_for!(struct MethodData { fn_data, container, has_self }); impl_stable_hash_for!(struct MethodData<'tcx> { fn_data, container, has_self });
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
pub struct ClosureData<'tcx> { pub struct ClosureData<'tcx> {

View File

@ -205,11 +205,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// FIXME(canndrew): This is_never should probably be an is_uninhabited // FIXME(canndrew): This is_never should probably be an is_uninhabited
let diverges = expr.ty.is_never(); let diverges = expr.ty.is_never();
let intrinsic = match ty.sty { let intrinsic = match ty.sty {
ty::TyFnDef(def_id, _, ref f) if ty::TyFnDef(def_id, _) => {
f.abi() == Abi::RustIntrinsic || let f = ty.fn_sig(this.hir.tcx());
f.abi() == Abi::PlatformIntrinsic => if f.abi() == Abi::RustIntrinsic ||
{ f.abi() == Abi::PlatformIntrinsic {
Some(this.hir.tcx().item_name(def_id).as_str()) Some(this.hir.tcx().item_name(def_id).as_str())
} else {
None
}
} }
_ => None _ => None
}; };

View File

@ -19,7 +19,6 @@ use rustc::middle::const_val::ConstVal;
use rustc::ty::{self, AdtKind, VariantDef, Ty}; use rustc::ty::{self, AdtKind, VariantDef, Ty};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
use rustc::ty::cast::CastKind as TyCastKind; use rustc::ty::cast::CastKind as TyCastKind;
use rustc::ty::subst::Subst;
use rustc::hir; use rustc::hir;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
@ -586,7 +585,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
}); });
Expr { Expr {
temp_lifetime: temp_lifetime, temp_lifetime: temp_lifetime,
ty: cx.tcx.type_of(def_id).subst(cx.tcx, substs), ty: cx.tcx().mk_fn_def(def_id, substs),
span: expr.span, span: expr.span,
kind: ExprKind::Literal { kind: ExprKind::Literal {
literal: Literal::Value { literal: Literal::Value {

View File

@ -58,7 +58,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
// types in the MIR. They will be substituted again with // types in the MIR. They will be substituted again with
// the param-substs, but because they are concrete, this // the param-substs, but because they are concrete, this
// will not do any harm. // will not do any harm.
let sig = tcx.erase_late_bound_regions(&ty.fn_sig()); let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
build_call_shim( build_call_shim(
@ -153,8 +153,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
} else { } else {
Substs::identity_for_item(tcx, def_id) Substs::identity_for_item(tcx, def_id)
}; };
let fn_ty = tcx.type_of(def_id).subst(tcx, substs); let sig = tcx.fn_sig(def_id).subst(tcx, substs);
let sig = tcx.erase_late_bound_regions(&fn_ty.fn_sig()); let sig = tcx.erase_late_bound_regions(&sig);
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let source_info = SourceInfo { span, scope: ARGUMENT_VISIBILITY_SCOPE }; let source_info = SourceInfo { span, scope: ARGUMENT_VISIBILITY_SCOPE };
@ -276,8 +276,8 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
call_kind={:?}, untuple_args={:?})", call_kind={:?}, untuple_args={:?})",
def_id, rcvr_adjustment, call_kind, untuple_args); def_id, rcvr_adjustment, call_kind, untuple_args);
let fn_ty = tcx.type_of(def_id); let sig = tcx.fn_sig(def_id);
let sig = tcx.erase_late_bound_regions(&fn_ty.fn_sig()); let sig = tcx.erase_late_bound_regions(&sig);
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
debug!("build_call_shim: sig={:?}", sig); debug!("build_call_shim: sig={:?}", sig);
@ -409,11 +409,8 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
{ {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let def_id = tcx.hir.local_def_id(ctor_id); let def_id = tcx.hir.local_def_id(ctor_id);
let sig = match tcx.type_of(def_id).sty { let sig = tcx.no_late_bound_regions(&tcx.fn_sig(def_id))
ty::TyFnDef(_, _, fty) => tcx.no_late_bound_regions(&fty) .expect("LBR in ADT constructor signature");
.expect("LBR in ADT constructor signature"),
_ => bug!("unexpected type for ctor {:?}", def_id)
};
let sig = tcx.erase_regions(&sig); let sig = tcx.erase_regions(&sig);
let (adt_def, substs) = match sig.output().sty { let (adt_def, substs) = match sig.output().sty {

View File

@ -87,7 +87,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let terminator = bb_data.terminator(); let terminator = bb_data.terminator();
if let TerminatorKind::Call { if let TerminatorKind::Call {
func: Operand::Constant(ref f), .. } = terminator.kind { func: Operand::Constant(ref f), .. } = terminator.kind {
if let ty::TyFnDef(callee_def_id, substs, _) = f.ty.sty { if let ty::TyFnDef(callee_def_id, substs) = f.ty.sty {
callsites.push_back(CallSite { callsites.push_back(CallSite {
callee: callee_def_id, callee: callee_def_id,
substs: substs, substs: substs,
@ -131,7 +131,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let terminator = bb_data.terminator(); let terminator = bb_data.terminator();
if let TerminatorKind::Call { if let TerminatorKind::Call {
func: Operand::Constant(ref f), .. } = terminator.kind { func: Operand::Constant(ref f), .. } = terminator.kind {
if let ty::TyFnDef(callee_def_id, substs, _) = f.ty.sty { if let ty::TyFnDef(callee_def_id, substs) = f.ty.sty {
// Don't inline the same function multiple times. // Don't inline the same function multiple times.
if callsite.callee != callee_def_id { if callsite.callee != callee_def_id {
callsites.push_back(CallSite { callsites.push_back(CallSite {
@ -270,8 +270,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
} }
TerminatorKind::Call {func: Operand::Constant(ref f), .. } => { TerminatorKind::Call {func: Operand::Constant(ref f), .. } => {
if let ty::TyFnDef(.., f) = f.ty.sty { if let ty::TyFnDef(def_id, _) = f.ty.sty {
// Don't give intrinsics the extra penalty for calls // Don't give intrinsics the extra penalty for calls
let f = tcx.fn_sig(def_id);
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic { if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
cost += INSTR_COST; cost += INSTR_COST;
} else { } else {

View File

@ -750,8 +750,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
let fn_ty = func.ty(self.mir, self.tcx); let fn_ty = func.ty(self.mir, self.tcx);
let (is_shuffle, is_const_fn) = match fn_ty.sty { let (is_shuffle, is_const_fn) = match fn_ty.sty {
ty::TyFnDef(def_id, _, f) => { ty::TyFnDef(def_id, _) => {
(f.abi() == Abi::PlatformIntrinsic && (self.tcx.fn_sig(def_id).abi() == Abi::PlatformIntrinsic &&
self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"), self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
self.tcx.is_const_fn(def_id)) self.tcx.is_const_fn(def_id))
} }

View File

@ -462,7 +462,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
let func_ty = func.ty(mir, tcx); let func_ty = func.ty(mir, tcx);
debug!("check_terminator: call, func_ty={:?}", func_ty); debug!("check_terminator: call, func_ty={:?}", func_ty);
let sig = match func_ty.sty { let sig = match func_ty.sty {
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => sig, ty::TyFnDef(..) | ty::TyFnPtr(_) => func_ty.fn_sig(tcx),
_ => { _ => {
span_mirbug!(self, term, "call to non-function {:?}", func_ty); span_mirbug!(self, term, "call to non-function {:?}", func_ty);
return; return;

View File

@ -400,7 +400,13 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
} }
fn ty(&mut self) -> &mut Self { fn ty(&mut self) -> &mut Self {
self.ev.tcx.type_of(self.item_def_id).visit_with(self); let ty = self.ev.tcx.type_of(self.item_def_id);
ty.visit_with(self);
if let ty::TyFnDef(def_id, _) = ty.sty {
if def_id == self.item_def_id {
self.ev.tcx.fn_sig(def_id).visit_with(self);
}
}
self self
} }
@ -910,7 +916,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
} }
fn ty(&mut self) -> &mut Self { fn ty(&mut self) -> &mut Self {
self.tcx.type_of(self.item_def_id).visit_with(self); let ty = self.tcx.type_of(self.item_def_id);
ty.visit_with(self);
if let ty::TyFnDef(def_id, _) = ty.sty {
if def_id == self.item_def_id {
self.tcx.fn_sig(def_id).visit_with(self);
}
}
self self
} }

View File

@ -154,6 +154,13 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
assert!(!item_type.has_erasable_regions()); assert!(!item_type.has_erasable_regions());
hasher.visit_ty(item_type); hasher.visit_ty(item_type);
// If this is a function, we hash the signature as well.
// This is not *strictly* needed, but it may help in some
// situations, see the `run-make/a-b-a-linker-guard` test.
if let ty::TyFnDef(..) = item_type.sty {
item_type.fn_sig(tcx).visit_with(&mut hasher);
}
// also include any type parameters (for generic items) // also include any type parameters (for generic items)
if let Some(substs) = substs { if let Some(substs) = substs {
assert!(!substs.has_erasable_regions()); assert!(!substs.has_erasable_regions());

View File

@ -587,7 +587,7 @@ fn visit_fn_use<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
is_direct_call: bool, is_direct_call: bool,
output: &mut Vec<TransItem<'tcx>>) output: &mut Vec<TransItem<'tcx>>)
{ {
if let ty::TyFnDef(def_id, substs, _) = ty.sty { if let ty::TyFnDef(def_id, substs) = ty.sty {
let instance = monomorphize::resolve(scx, def_id, substs); let instance = monomorphize::resolve(scx, def_id, substs);
visit_instance_use(scx, instance, is_direct_call, output); visit_instance_use(scx, instance, is_direct_call, output);
} }

View File

@ -495,9 +495,9 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-> ty::PolyFnSig<'tcx> -> ty::PolyFnSig<'tcx>
{ {
match ty.sty { match ty.sty {
ty::TyFnDef(_, _, sig) => sig, ty::TyFnDef(..) |
// Shims currently have type TyFnPtr. Not sure this should remain. // Shims currently have type TyFnPtr. Not sure this should remain.
ty::TyFnPtr(sig) => sig, ty::TyFnPtr(_) => ty.fn_sig(ccx.tcx()),
ty::TyClosure(def_id, substs) => { ty::TyClosure(def_id, substs) => {
let tcx = ccx.tcx(); let tcx = ccx.tcx();
let sig = tcx.fn_sig(def_id).subst(tcx, substs.substs); let sig = tcx.fn_sig(def_id).subst(tcx, substs.substs);

View File

@ -488,7 +488,6 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
debug!("type_metadata: {:?}", t); debug!("type_metadata: {:?}", t);
let sty = &t.sty;
let ptr_metadata = |ty: Ty<'tcx>| { let ptr_metadata = |ty: Ty<'tcx>| {
match ty.sty { match ty.sty {
ty::TySlice(typ) => { ty::TySlice(typ) => {
@ -518,7 +517,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
} }
}; };
let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty { let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.sty {
ty::TyNever | ty::TyNever |
ty::TyBool | ty::TyBool |
ty::TyChar | ty::TyChar |
@ -557,10 +556,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Err(metadata) => return metadata, Err(metadata) => return metadata,
} }
} }
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => { ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let fn_metadata = subroutine_type_metadata(cx, let fn_metadata = subroutine_type_metadata(cx,
unique_type_id, unique_type_id,
sig, t.fn_sig(cx.tcx()),
usage_site_span).metadata; usage_site_span).metadata;
match debug_context(cx).type_map match debug_context(cx).type_map
.borrow() .borrow()
@ -610,7 +609,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
usage_site_span).finalize(cx) usage_site_span).finalize(cx)
} }
_ => { _ => {
bug!("debuginfo: unexpected type in type_metadata: {:?}", sty) bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
} }
}; };

View File

@ -96,8 +96,8 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
push_type_params(cx, principal.substs, output); push_type_params(cx, principal.substs, output);
} }
}, },
ty::TyFnDef(.., sig) | ty::TyFnDef(..) | ty::TyFnPtr(_) => {
ty::TyFnPtr(sig) => { let sig = t.fn_sig(cx.tcx());
if sig.unsafety() == hir::Unsafety::Unsafe { if sig.unsafety() == hir::Unsafety::Unsafe {
output.push_str("unsafe "); output.push_str("unsafe ");
} }

View File

@ -95,11 +95,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
let ccx = bcx.ccx; let ccx = bcx.ccx;
let tcx = ccx.tcx(); let tcx = ccx.tcx();
let (def_id, substs, sig) = match callee_ty.sty { let (def_id, substs) = match callee_ty.sty {
ty::TyFnDef(def_id, substs, sig) => (def_id, substs, sig), ty::TyFnDef(def_id, substs) => (def_id, substs),
_ => bug!("expected fn item type, found {}", callee_ty) _ => bug!("expected fn item type, found {}", callee_ty)
}; };
let sig = callee_ty.fn_sig(tcx);
let sig = tcx.erase_late_bound_regions_and_normalize(&sig); let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
let ret_ty = sig.output(); let ret_ty = sig.output();
@ -986,7 +987,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
let tcx = bcx.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(tcx));
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
// every intrinsic takes a SIMD vector as its first argument // every intrinsic takes a SIMD vector as its first argument

View File

@ -404,20 +404,18 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar. // 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 callee = self.trans_operand(&bcx, func);
let (instance, mut llfn, sig) = match callee.ty.sty { let (instance, mut llfn) = match callee.ty.sty {
ty::TyFnDef(def_id, substs, sig) => { ty::TyFnDef(def_id, substs) => {
(Some(monomorphize::resolve(bcx.ccx.shared(), def_id, substs)), (Some(monomorphize::resolve(bcx.ccx.shared(), def_id, substs)),
None, None)
sig)
} }
ty::TyFnPtr(sig) => { ty::TyFnPtr(_) => {
(None, (None, Some(callee.immediate()))
Some(callee.immediate()),
sig)
} }
_ => bug!("{} is not callable", callee.ty) _ => bug!("{} is not callable", callee.ty)
}; };
let def = instance.map(|i| i.def); let def = instance.map(|i| i.def);
let sig = callee.ty.fn_sig(bcx.tcx());
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; let abi = sig.abi;

View File

@ -334,7 +334,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let fn_ty = func.ty(self.mir, tcx); let fn_ty = func.ty(self.mir, tcx);
let fn_ty = self.monomorphize(&fn_ty); let fn_ty = self.monomorphize(&fn_ty);
let (def_id, substs) = match fn_ty.sty { let (def_id, substs) = match fn_ty.sty {
ty::TyFnDef(def_id, substs, _) => (def_id, substs), ty::TyFnDef(def_id, substs) => (def_id, substs),
_ => span_bug!(span, "calling {:?} (of type {}) in constant", _ => span_bug!(span, "calling {:?} (of type {}) in constant",
func, fn_ty) func, fn_ty)
}; };
@ -560,7 +560,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let val = match *kind { let val = match *kind {
mir::CastKind::ReifyFnPointer => { mir::CastKind::ReifyFnPointer => {
match operand.ty.sty { match operand.ty.sty {
ty::TyFnDef(def_id, substs, _) => { ty::TyFnDef(def_id, substs) => {
callee::resolve_and_get_fn(self.ccx, def_id, substs) callee::resolve_and_get_fn(self.ccx, def_id, substs)
} }
_ => { _ => {

View File

@ -180,7 +180,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
let val = match *kind { let val = match *kind {
mir::CastKind::ReifyFnPointer => { mir::CastKind::ReifyFnPointer => {
match operand.ty.sty { match operand.ty.sty {
ty::TyFnDef(def_id, substs, _) => { ty::TyFnDef(def_id, substs) => {
OperandValue::Immediate( OperandValue::Immediate(
callee::resolve_and_get_fn(bcx.ccx, def_id, substs)) callee::resolve_and_get_fn(bcx.ccx, def_id, substs))
} }

View File

@ -165,9 +165,11 @@ pub fn resolve<'a, 'tcx>(
} else { } else {
let item_type = def_ty(scx, def_id, substs); let item_type = def_ty(scx, def_id, substs);
let def = match item_type.sty { let def = match item_type.sty {
ty::TyFnDef(_, _, f) if ty::TyFnDef(..) if {
f.abi() == Abi::RustIntrinsic || let f = item_type.fn_sig(scx.tcx());
f.abi() == Abi::PlatformIntrinsic => f.abi() == Abi::RustIntrinsic ||
f.abi() == Abi::PlatformIntrinsic
} =>
{ {
debug!(" => intrinsic"); debug!(" => intrinsic");
ty::InstanceDef::Intrinsic(def_id) ty::InstanceDef::Intrinsic(def_id)

View File

@ -401,8 +401,9 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
output); output);
} }
}, },
ty::TyFnDef(.., sig) | ty::TyFnDef(..) |
ty::TyFnPtr(sig) => { ty::TyFnPtr(_) => {
let sig = t.fn_sig(self.tcx);
if sig.unsafety() == hir::Unsafety::Unsafe { if sig.unsafety() == hir::Unsafety::Unsafe {
output.push_str("unsafe "); output.push_str("unsafe ");
} }

View File

@ -619,7 +619,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Type check the path. // Type check the path.
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id); let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
// Replace constructor type with constructed type for tuple struct patterns. // Replace constructor type with constructed type for tuple struct patterns.
let pat_ty = pat_ty.fn_sig().output(); let pat_ty = pat_ty.fn_sig(tcx).output();
let pat_ty = tcx.no_late_bound_regions(&pat_ty).expect("expected fn type"); let pat_ty = tcx.no_late_bound_regions(&pat_ty).expect("expected fn type");
self.demand_eqtype(pat.span, expected, pat_ty); self.demand_eqtype(pat.span, expected, pat_ty);

View File

@ -196,8 +196,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expected: Expectation<'tcx>) expected: Expectation<'tcx>)
-> Ty<'tcx> { -> Ty<'tcx> {
let (fn_sig, def_span) = match callee_ty.sty { let (fn_sig, def_span) = match callee_ty.sty {
ty::TyFnDef(def_id, .., sig) => { ty::TyFnDef(def_id, _) => {
(sig, self.tcx.hir.span_if_local(def_id)) (callee_ty.fn_sig(self.tcx), self.tcx.hir.span_if_local(def_id))
} }
ty::TyFnPtr(sig) => (sig, None), ty::TyFnPtr(sig) => (sig, None),
ref t => { ref t => {

View File

@ -356,8 +356,9 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
(Some(t_from), Some(t_cast)) => (t_from, t_cast), (Some(t_from), Some(t_cast)) => (t_from, t_cast),
// Function item types may need to be reified before casts. // Function item types may need to be reified before casts.
(None, Some(t_cast)) => { (None, Some(t_cast)) => {
if let ty::TyFnDef(.., f) = self.expr_ty.sty { if let ty::TyFnDef(..) = self.expr_ty.sty {
// Attempt a coercion to a fn pointer type. // Attempt a coercion to a fn pointer type.
let f = self.expr_ty.fn_sig(fcx.tcx);
let res = fcx.try_coerce(self.expr, let res = fcx.try_coerce(self.expr,
self.expr_ty, self.expr_ty,
self.expr_diverges, self.expr_diverges,

View File

@ -210,13 +210,13 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
} }
match a.sty { match a.sty {
ty::TyFnDef(.., a_f) => { ty::TyFnDef(..) => {
// Function items are coercible to any closure // Function items are coercible to any closure
// type; function pointers are not (that would // type; function pointers are not (that would
// require double indirection). // require double indirection).
// Additionally, we permit coercion of function // Additionally, we permit coercion of function
// items to drop the unsafe qualifier. // items to drop the unsafe qualifier.
self.coerce_from_fn_item(a, a_f, b) self.coerce_from_fn_item(a, b)
} }
ty::TyFnPtr(a_f) => { ty::TyFnPtr(a_f) => {
// We permit coercion of fn pointers to drop the // We permit coercion of fn pointers to drop the
@ -600,7 +600,6 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
fn coerce_from_fn_item(&self, fn coerce_from_fn_item(&self,
a: Ty<'tcx>, a: Ty<'tcx>,
fn_ty_a: ty::PolyFnSig<'tcx>,
b: Ty<'tcx>) b: Ty<'tcx>)
-> CoerceResult<'tcx> { -> CoerceResult<'tcx> {
//! Attempts to coerce from the type of a Rust function item //! Attempts to coerce from the type of a Rust function item
@ -612,9 +611,17 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
match b.sty { match b.sty {
ty::TyFnPtr(_) => { ty::TyFnPtr(_) => {
let a_fn_pointer = self.tcx.mk_fn_ptr(fn_ty_a); let a_sig = a.fn_sig(self.tcx);
self.coerce_from_safe_fn(a_fn_pointer, fn_ty_a, b, let InferOk { value: a_sig, mut obligations } =
simple(Adjust::ReifyFnPointer), simple(Adjust::ReifyFnPointer)) self.normalize_associated_types_in_as_infer_ok(self.cause.span, &a_sig);
let a_fn_pointer = self.tcx.mk_fn_ptr(a_sig);
let InferOk { value, obligations: o2 } =
self.coerce_from_safe_fn(a_fn_pointer, a_sig, b,
simple(Adjust::ReifyFnPointer), simple(Adjust::ReifyFnPointer))?;
obligations.extend(o2);
Ok(InferOk { value, obligations })
} }
_ => self.unify_and(a, b, identity), _ => self.unify_and(a, b, identity),
} }
@ -775,42 +782,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Special-case that coercion alone cannot handle: // Special-case that coercion alone cannot handle:
// Two function item types of differing IDs or Substs. // Two function item types of differing IDs or Substs.
match (&prev_ty.sty, &new_ty.sty) { if let (&ty::TyFnDef(..), &ty::TyFnDef(..)) = (&prev_ty.sty, &new_ty.sty) {
(&ty::TyFnDef(a_def_id, a_substs, a_fty), &ty::TyFnDef(b_def_id, b_substs, b_fty)) => { // Don't reify if the function types have a LUB, i.e. they
// The signature must always match. // are the same function and their parameters have a LUB.
let fty = self.at(cause, self.param_env) let lub_ty = self.commit_if_ok(|_| {
.trace(prev_ty, new_ty) self.at(cause, self.param_env)
.lub(&a_fty, &b_fty) .lub(prev_ty, new_ty)
.map(|ok| self.register_infer_ok_obligations(ok))?; .map(|ok| self.register_infer_ok_obligations(ok))
});
if a_def_id == b_def_id { if lub_ty.is_ok() {
// Same function, maybe the parameters match. // We have a LUB of prev_ty and new_ty, just return it.
let substs = self.commit_if_ok(|_| { return lub_ty;
self.at(cause, self.param_env)
.trace(prev_ty, new_ty)
.lub(&a_substs, &b_substs)
.map(|ok| self.register_infer_ok_obligations(ok))
});
if let Ok(substs) = substs {
// We have a LUB of prev_ty and new_ty, just return it.
return Ok(self.tcx.mk_fn_def(a_def_id, substs, fty));
}
}
// Reify both sides and return the reified fn pointer type.
let fn_ptr = self.tcx.mk_fn_ptr(fty);
for expr in exprs.iter().map(|e| e.as_coercion_site()).chain(Some(new)) {
// The only adjustment that can produce an fn item is
// `NeverToAny`, so this should always be valid.
self.apply_adjustments(expr, vec![Adjustment {
kind: Adjust::ReifyFnPointer,
target: fn_ptr
}]);
}
return Ok(fn_ptr);
} }
_ => {}
// The signature must match.
let a_sig = prev_ty.fn_sig(self.tcx);
let a_sig = self.normalize_associated_types_in(new.span, &a_sig);
let b_sig = new_ty.fn_sig(self.tcx);
let b_sig = self.normalize_associated_types_in(new.span, &b_sig);
let sig = self.at(cause, self.param_env)
.trace(prev_ty, new_ty)
.lub(&a_sig, &b_sig)
.map(|ok| self.register_infer_ok_obligations(ok))?;
// Reify both sides and return the reified fn pointer type.
let fn_ptr = self.tcx.mk_fn_ptr(sig);
for expr in exprs.iter().map(|e| e.as_coercion_site()).chain(Some(new)) {
// The only adjustment that can produce an fn item is
// `NeverToAny`, so this should always be valid.
self.apply_adjustments(expr, vec![Adjustment {
kind: Adjust::ReifyFnPointer,
target: fn_ptr
}]);
}
return Ok(fn_ptr);
} }
let mut coerce = Coerce::new(self, cause.clone()); let mut coerce = Coerce::new(self, cause.clone());

View File

@ -256,17 +256,10 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Compute skolemized form of impl and trait method tys. // Compute skolemized form of impl and trait method tys.
let tcx = infcx.tcx; let tcx = infcx.tcx;
let m_sig = |method: &ty::AssociatedItem| {
match tcx.type_of(method.def_id).sty {
ty::TyFnDef(_, _, f) => f,
_ => bug!()
}
};
let (impl_sig, _) = let (impl_sig, _) =
infcx.replace_late_bound_regions_with_fresh_var(impl_m_span, infcx.replace_late_bound_regions_with_fresh_var(impl_m_span,
infer::HigherRankedType, infer::HigherRankedType,
&m_sig(impl_m)); &tcx.fn_sig(impl_m.def_id));
let impl_sig = let impl_sig =
inh.normalize_associated_types_in(impl_m_span, inh.normalize_associated_types_in(impl_m_span,
impl_m_node_id, impl_m_node_id,
@ -277,7 +270,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let trait_sig = inh.liberate_late_bound_regions( let trait_sig = inh.liberate_late_bound_regions(
impl_m.def_id, impl_m.def_id,
&m_sig(trait_m)); &tcx.fn_sig(trait_m.def_id));
let trait_sig = let trait_sig =
trait_sig.subst(tcx, trait_to_skol_substs); trait_sig.subst(tcx, trait_to_skol_substs);
let trait_sig = let trait_sig =
@ -507,8 +500,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty::ImplContainer(_) => impl_trait_ref.self_ty(), ty::ImplContainer(_) => impl_trait_ref.self_ty(),
ty::TraitContainer(_) => tcx.mk_self_type() ty::TraitContainer(_) => tcx.mk_self_type()
}; };
let method_ty = tcx.type_of(method.def_id); let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
let self_arg_ty = *method_ty.fn_sig().input(0).skip_binder();
match ExplicitSelf::determine(untransformed_self_ty, self_arg_ty) { match ExplicitSelf::determine(untransformed_self_ty, self_arg_ty) {
ExplicitSelf::ByValue => "self".to_string(), ExplicitSelf::ByValue => "self".to_string(),
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(), ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
@ -637,14 +629,8 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_m: &ty::AssociatedItem, trait_m: &ty::AssociatedItem,
trait_item_span: Option<Span>) trait_item_span: Option<Span>)
-> Result<(), ErrorReported> { -> Result<(), ErrorReported> {
let m_fty = |method: &ty::AssociatedItem| { let impl_m_fty = tcx.fn_sig(impl_m.def_id);
match tcx.type_of(method.def_id).sty { let trait_m_fty = tcx.fn_sig(trait_m.def_id);
ty::TyFnDef(_, _, f) => f,
_ => bug!()
}
};
let impl_m_fty = m_fty(impl_m);
let trait_m_fty = m_fty(trait_m);
let trait_number_args = trait_m_fty.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(); let impl_number_args = impl_m_fty.inputs().skip_binder().len();
if trait_number_args != impl_number_args { if trait_number_args != impl_number_args {

View File

@ -143,12 +143,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn has_no_input_arg(&self, method: &AssociatedItem) -> bool { fn has_no_input_arg(&self, method: &AssociatedItem) -> bool {
match method.def() { match method.def() {
Def::Method(def_id) => { Def::Method(def_id) => {
match self.tcx.type_of(def_id).sty { self.tcx.fn_sig(def_id).inputs().skip_binder().len() == 1
ty::TypeVariants::TyFnDef(_, _, sig) => {
sig.inputs().skip_binder().len() == 1
}
_ => false,
}
} }
_ => false, _ => false,
} }

View File

@ -13,7 +13,6 @@
use intrinsics; use intrinsics;
use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::traits::{ObligationCause, ObligationCauseCode};
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt, Ty}; use rustc::ty::{self, TyCtxt, Ty};
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use require_same_types; use require_same_types;
@ -35,22 +34,22 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
output: Ty<'tcx>) { output: Ty<'tcx>) {
let def_id = tcx.hir.local_def_id(it.id); let def_id = tcx.hir.local_def_id(it.id);
let substs = Substs::for_item(tcx, def_id, match it.node {
|_, _| tcx.types.re_erased, hir::ForeignItemFn(..) => {}
|def, _| tcx.mk_param_from_def(def)); _ => {
struct_span_err!(tcx.sess, it.span, E0619,
"intrinsic must be a function")
.span_label(it.span, "expected a function")
.emit();
return;
}
}
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.generics_of(def_id).types.len(); let i_n_tps = tcx.generics_of(def_id).types.len();
if i_n_tps != n_tps { if i_n_tps != n_tps {
let span = match it.node { let span = match it.node {
hir::ForeignItemFn(_, _, ref generics) => generics.span, hir::ForeignItemFn(_, _, ref generics) => generics.span,
hir::ForeignItemStatic(..) => it.span _ => bug!()
}; };
struct_span_err!(tcx.sess, span, E0094, struct_span_err!(tcx.sess, span, E0094,
@ -59,14 +58,18 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
i_n_tps, n_tps) i_n_tps, n_tps)
.span_label(span, format!("expected {} type parameter", n_tps)) .span_label(span, format!("expected {} type parameter", n_tps))
.emit(); .emit();
} else { return;
require_same_types(tcx,
&ObligationCause::new(it.span,
it.id,
ObligationCauseCode::IntrinsicType),
tcx.type_of(def_id),
fty);
} }
let fty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
inputs.into_iter(),
output,
false,
hir::Unsafety::Unsafe,
abi
)));
let cause = ObligationCause::new(it.span, it.id, ObligationCauseCode::IntrinsicType);
require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty);
} }
/// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs, /// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
@ -376,7 +379,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut structural_to_nomimal = FxHashMap(); let mut structural_to_nomimal = FxHashMap();
let sig = tcx.type_of(def_id).fn_sig(); let sig = tcx.fn_sig(def_id);
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() { if intr.inputs.len() != sig.inputs().len() {
span_err!(tcx.sess, it.span, E0444, span_err!(tcx.sess, it.span, E0444,

View File

@ -375,7 +375,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
debug!("method_predicates after subst = {:?}", method_predicates); debug!("method_predicates after subst = {:?}", method_predicates);
let sig = self.tcx.type_of(def_id).fn_sig(); let sig = self.tcx.fn_sig(def_id);
// Instantiate late-bound regions and substitute the trait // Instantiate late-bound regions and substitute the trait
// parameters into the method type to get the actual method type. // parameters into the method type to get the actual method type.

View File

@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// NB: Instantiate late-bound regions first so that // NB: Instantiate late-bound regions first so that
// `instantiate_type_scheme` can normalize associated types that // `instantiate_type_scheme` can normalize associated types that
// may reference those regions. // may reference those regions.
let fn_sig = tcx.type_of(def_id).fn_sig(); let fn_sig = tcx.fn_sig(def_id);
let fn_sig = self.replace_late_bound_regions_with_fresh_var(span, let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
infer::FnCall, infer::FnCall,
&fn_sig).0; &fn_sig).0;

View File

@ -673,7 +673,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
expected: ty::Ty<'tcx>) -> bool { expected: ty::Ty<'tcx>) -> bool {
match method.def() { match method.def() {
Def::Method(def_id) => { Def::Method(def_id) => {
let fty = self.tcx.type_of(def_id).fn_sig(); let fty = self.tcx.fn_sig(def_id);
self.probe(|_| { self.probe(|_| {
let substs = self.fresh_substs_for_item(self.span, method.def_id); let substs = self.fresh_substs_for_item(self.span, method.def_id);
let output = fty.output().subst(self.tcx, substs); let output = fty.output().subst(self.tcx, substs);
@ -1288,7 +1288,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
impl_ty: Ty<'tcx>, impl_ty: Ty<'tcx>,
substs: &Substs<'tcx>) substs: &Substs<'tcx>)
-> Ty<'tcx> { -> Ty<'tcx> {
let self_ty = self.tcx.type_of(method).fn_sig().input(0); let self_ty = self.tcx.fn_sig(method).input(0);
debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})", debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})",
impl_ty, impl_ty,
self_ty, self_ty,

View File

@ -718,20 +718,12 @@ pub fn provide(providers: &mut Providers) {
typeck_item_bodies, typeck_item_bodies,
typeck_tables_of, typeck_tables_of,
has_typeck_tables, has_typeck_tables,
fn_sig,
closure_kind, closure_kind,
adt_destructor, adt_destructor,
..*providers ..*providers
}; };
} }
fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ty::PolyFnSig<'tcx> {
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
tcx.typeck_tables_of(def_id).closure_tys[&node_id]
}
fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId) def_id: DefId)
-> ty::ClosureKind { -> ty::ClosureKind {
@ -844,7 +836,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Inherited::build(tcx, def_id).enter(|inh| { Inherited::build(tcx, def_id).enter(|inh| {
let param_env = tcx.param_env(def_id); let param_env = tcx.param_env(def_id);
let fcx = if let Some(decl) = fn_decl { let fcx = if let Some(decl) = fn_decl {
let fn_sig = tcx.type_of(def_id).fn_sig(); let fn_sig = tcx.fn_sig(def_id);
check_abi(tcx, span, fn_sig.abi()); check_abi(tcx, span, fn_sig.abi());
@ -2173,7 +2165,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-> ty::TypeAndMut<'tcx> -> ty::TypeAndMut<'tcx>
{ {
// extract method return type, which will be &T; // extract method return type, which will be &T;
// all LB regions should have been instantiated during method lookup
let ret_ty = method.sig.output(); let ret_ty = method.sig.output();
// method returns &T, but the type as visible to user is T, so deref // method returns &T, but the type as visible to user is T, so deref
@ -2580,8 +2571,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => { ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint"); variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
} }
ty::TyFnDef(.., f) => { ty::TyFnDef(..) => {
let ptr_ty = self.tcx.mk_fn_ptr(f); let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty); let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty)); variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
} }

View File

@ -177,12 +177,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
} }
ty::AssociatedKind::Method => { ty::AssociatedKind::Method => {
reject_shadowing_type_parameters(fcx.tcx, item.def_id); reject_shadowing_type_parameters(fcx.tcx, item.def_id);
let method_ty = fcx.tcx.type_of(item.def_id); let sig = fcx.tcx.fn_sig(item.def_id);
let method_ty = fcx.normalize_associated_types_in(span, &method_ty); let sig = fcx.normalize_associated_types_in(span, &sig);
let predicates = fcx.tcx.predicates_of(item.def_id) let predicates = fcx.tcx.predicates_of(item.def_id)
.instantiate_identity(fcx.tcx); .instantiate_identity(fcx.tcx);
let predicates = fcx.normalize_associated_types_in(span, &predicates); let predicates = fcx.normalize_associated_types_in(span, &predicates);
let sig = method_ty.fn_sig();
this.check_fn_or_method(fcx, span, sig, &predicates, this.check_fn_or_method(fcx, span, sig, &predicates,
item.def_id, &mut implied_bounds); item.def_id, &mut implied_bounds);
let sig_if_method = sig_if_method.expect("bad signature for method"); let sig_if_method = sig_if_method.expect("bad signature for method");
@ -331,9 +330,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
fn check_item_fn(&mut self, item: &hir::Item) { fn check_item_fn(&mut self, item: &hir::Item) {
self.for_item(item).with_fcx(|fcx, this| { self.for_item(item).with_fcx(|fcx, this| {
let def_id = fcx.tcx.hir.local_def_id(item.id); let def_id = fcx.tcx.hir.local_def_id(item.id);
let ty = fcx.tcx.type_of(def_id); let sig = fcx.tcx.fn_sig(def_id);
let item_ty = fcx.normalize_associated_types_in(item.span, &ty); let sig = fcx.normalize_associated_types_in(item.span, &sig);
let sig = item_ty.fn_sig();
let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx); let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx);
let predicates = fcx.normalize_associated_types_in(item.span, &predicates); let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
@ -461,9 +459,9 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
let span = method_sig.decl.inputs[0].span; let span = method_sig.decl.inputs[0].span;
let method_ty = fcx.tcx.type_of(method.def_id); let sig = fcx.tcx.fn_sig(method.def_id);
let fty = fcx.normalize_associated_types_in(span, &method_ty); let sig = fcx.normalize_associated_types_in(span, &sig);
let sig = fcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig()); let sig = fcx.liberate_late_bound_regions(method.def_id, &sig);
debug!("check_method_receiver: sig={:?}", sig); debug!("check_method_receiver: sig={:?}", sig);

View File

@ -97,6 +97,7 @@ pub fn provide(providers: &mut Providers) {
type_param_predicates, type_param_predicates,
trait_def, trait_def,
adt_def, adt_def,
fn_sig,
impl_trait_ref, impl_trait_ref,
impl_polarity, impl_polarity,
is_foreign_item, is_foreign_item,
@ -447,6 +448,9 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
tcx.generics_of(def_id); tcx.generics_of(def_id);
tcx.type_of(def_id); tcx.type_of(def_id);
tcx.predicates_of(def_id); tcx.predicates_of(def_id);
if let hir::ForeignItemFn(..) = item.node {
tcx.fn_sig(def_id);
}
} }
} }
hir::ItemEnum(ref enum_definition, _) => { hir::ItemEnum(ref enum_definition, _) => {
@ -497,6 +501,9 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
tcx.generics_of(def_id); tcx.generics_of(def_id);
tcx.type_of(def_id); tcx.type_of(def_id);
tcx.predicates_of(def_id); tcx.predicates_of(def_id);
if let hir::ItemFn(..) = it.node {
tcx.fn_sig(def_id);
}
} }
} }
} }
@ -511,6 +518,9 @@ fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast:
hir::TraitItemKind::Type(_, Some(_)) | hir::TraitItemKind::Type(_, Some(_)) |
hir::TraitItemKind::Method(..) => { hir::TraitItemKind::Method(..) => {
tcx.type_of(def_id); tcx.type_of(def_id);
if let hir::TraitItemKind::Method(..) = trait_item.node {
tcx.fn_sig(def_id);
}
} }
hir::TraitItemKind::Type(_, None) => {} hir::TraitItemKind::Type(_, None) => {}
@ -524,6 +534,9 @@ fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::N
tcx.generics_of(def_id); tcx.generics_of(def_id);
tcx.type_of(def_id); tcx.type_of(def_id);
tcx.predicates_of(def_id); tcx.predicates_of(def_id);
if let hir::ImplItemKind::Method(..) = tcx.hir.expect_impl_item(impl_item_id).node {
tcx.fn_sig(def_id);
}
} }
fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@ -963,10 +976,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
match tcx.hir.get(node_id) { match tcx.hir.get(node_id) {
NodeTraitItem(item) => { NodeTraitItem(item) => {
match item.node { match item.node {
TraitItemKind::Method(ref sig, _) => { TraitItemKind::Method(..) => {
let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
let substs = Substs::identity_for_item(tcx, def_id); let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs, fty) tcx.mk_fn_def(def_id, substs)
} }
TraitItemKind::Const(ref ty, _) | TraitItemKind::Const(ref ty, _) |
TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty), TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
@ -978,10 +990,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
NodeImplItem(item) => { NodeImplItem(item) => {
match item.node { match item.node {
ImplItemKind::Method(ref sig, _) => { ImplItemKind::Method(..) => {
let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
let substs = Substs::identity_for_item(tcx, def_id); let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs, fty) tcx.mk_fn_def(def_id, substs)
} }
ImplItemKind::Const(ref ty, _) => icx.to_ty(ty), ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
ImplItemKind::Type(ref ty) => { ImplItemKind::Type(ref ty) => {
@ -1001,10 +1012,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ItemTy(ref t, _) | ItemImpl(.., ref t, _) => { ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
icx.to_ty(t) icx.to_ty(t)
} }
ItemFn(ref decl, unsafety, _, abi, _, _) => { ItemFn(..) => {
let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl);
let substs = Substs::identity_for_item(tcx, def_id); let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs, tofd) tcx.mk_fn_def(def_id, substs)
} }
ItemEnum(..) | ItemEnum(..) |
ItemStruct(..) | ItemStruct(..) |
@ -1029,11 +1039,10 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} }
NodeForeignItem(foreign_item) => { NodeForeignItem(foreign_item) => {
let abi = tcx.hir.get_foreign_abi(node_id);
match foreign_item.node { match foreign_item.node {
ForeignItemFn(ref fn_decl, _, _) => { ForeignItemFn(..) => {
compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi) let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs)
} }
ForeignItemStatic(ref t, _) => icx.to_ty(t) ForeignItemStatic(ref t, _) => icx.to_ty(t)
} }
@ -1041,21 +1050,13 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
NodeStructCtor(&ref def) | NodeStructCtor(&ref def) |
NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => { NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
match *def { match *def {
VariantData::Unit(..) | VariantData::Struct(..) => ty, VariantData::Unit(..) | VariantData::Struct(..) => {
VariantData::Tuple(ref fields, _) => { tcx.type_of(tcx.hir.get_parent_did(node_id))
let inputs = fields.iter().map(|f| { }
tcx.type_of(tcx.hir.local_def_id(f.id)) VariantData::Tuple(..) => {
});
let substs = Substs::identity_for_item(tcx, def_id); let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig( tcx.mk_fn_def(def_id, substs)
inputs,
ty,
false,
hir::Unsafety::Normal,
abi::Abi::Rust
)))
} }
} }
} }
@ -1105,6 +1106,58 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} }
} }
fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ty::PolyFnSig<'tcx> {
use rustc::hir::map::*;
use rustc::hir::*;
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
let icx = ItemCtxt::new(tcx, def_id);
match tcx.hir.get(node_id) {
NodeTraitItem(&hir::TraitItem { node: TraitItemKind::Method(ref sig, _), .. }) |
NodeImplItem(&hir::ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) => {
AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl)
}
NodeItem(&hir::Item { node: ItemFn(ref decl, unsafety, _, abi, _, _), .. }) => {
AstConv::ty_of_fn(&icx, unsafety, abi, decl)
}
NodeForeignItem(&hir::ForeignItem { node: ForeignItemFn(ref fn_decl, _, _), .. }) => {
let abi = tcx.hir.get_foreign_abi(node_id);
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
}
NodeStructCtor(&VariantData::Tuple(ref fields, _)) |
NodeVariant(&Spanned { node: hir::Variant_ {
data: VariantData::Tuple(ref fields, _), ..
}, .. }) => {
let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
let inputs = fields.iter().map(|f| {
tcx.type_of(tcx.hir.local_def_id(f.id))
});
ty::Binder(tcx.mk_fn_sig(
inputs,
ty,
false,
hir::Unsafety::Normal,
abi::Abi::Rust
))
}
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
tcx.typeck_tables_of(def_id).closure_tys[&node_id]
}
x => {
bug!("unexpected sort of node in fn_sig(): {:?}", x);
}
}
}
fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId) def_id: DefId)
-> Option<ty::TraitRef<'tcx>> { -> Option<ty::TraitRef<'tcx>> {
@ -1502,12 +1555,12 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
} }
} }
fn compute_type_of_foreign_fn_decl<'a, 'tcx>( fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId, def_id: DefId,
decl: &hir::FnDecl, decl: &hir::FnDecl,
abi: abi::Abi) abi: abi::Abi)
-> Ty<'tcx> -> ty::PolyFnSig<'tcx>
{ {
let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl); let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
@ -1533,8 +1586,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
} }
} }
let substs = Substs::identity_for_item(tcx, def_id); fty
tcx.mk_fn_def(def_id, substs, fty)
} }
fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

View File

@ -4736,4 +4736,5 @@ register_diagnostics! {
E0568, // auto-traits can not have predicates, E0568, // auto-traits can not have predicates,
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
E0592, // duplicate definitions with name `{}` E0592, // duplicate definitions with name `{}`
E0619, // intrinsic must be a function
} }

View File

@ -198,22 +198,21 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} }
_ => () _ => ()
} }
let substs = tcx.intern_substs(&[]); let se_ty = tcx.mk_fn_ptr(ty::Binder(
let se_ty = tcx.mk_fn_def(main_def_id, substs, tcx.mk_fn_sig(
ty::Binder(tcx.mk_fn_sig(
iter::empty(), iter::empty(),
tcx.mk_nil(), tcx.mk_nil(),
false, false,
hir::Unsafety::Normal, hir::Unsafety::Normal,
Abi::Rust Abi::Rust
)) )
); ));
require_same_types( require_same_types(
tcx, tcx,
&ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType), &ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
se_ty, se_ty,
main_t); tcx.mk_fn_ptr(tcx.fn_sig(main_def_id)));
} }
_ => { _ => {
span_bug!(main_span, span_bug!(main_span,
@ -248,9 +247,8 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
_ => () _ => ()
} }
let substs = tcx.intern_substs(&[]); let se_ty = tcx.mk_fn_ptr(ty::Binder(
let se_ty = tcx.mk_fn_def(start_def_id, substs, tcx.mk_fn_sig(
ty::Binder(tcx.mk_fn_sig(
[ [
tcx.types.isize, tcx.types.isize,
tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8)) tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
@ -259,14 +257,14 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
false, false,
hir::Unsafety::Normal, hir::Unsafety::Normal,
Abi::Rust Abi::Rust
)) )
); ));
require_same_types( require_same_types(
tcx, tcx,
&ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType), &ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
se_ty, se_ty,
start_t); tcx.mk_fn_ptr(tcx.fn_sig(start_def_id)));
} }
_ => { _ => {
span_bug!(start_span, span_bug!(start_span,

View File

@ -382,6 +382,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// leaf type -- noop // leaf type -- noop
} }
ty::TyFnDef(..) |
ty::TyClosure(..) | ty::TyClosure(..) |
ty::TyAnon(..) => { ty::TyAnon(..) => {
bug!("Unexpected closure type in variance computation"); bug!("Unexpected closure type in variance computation");
@ -466,7 +467,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
} }
} }
ty::TyFnDef(.., sig) |
ty::TyFnPtr(sig) => { ty::TyFnPtr(sig) => {
self.add_constraints_from_sig(current, sig, variance); self.add_constraints_from_sig(current, sig, variance);
} }

View File

@ -149,7 +149,7 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
} }
fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function { fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
let sig = cx.tcx.type_of(did).fn_sig(); let sig = cx.tcx.fn_sig(did);
let constness = if cx.tcx.is_const_fn(did) { let constness = if cx.tcx.is_const_fn(did) {
hir::Constness::Const hir::Constness::Const

View File

@ -1367,7 +1367,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
ty::AssociatedKind::Method => { ty::AssociatedKind::Method => {
let generics = (cx.tcx.generics_of(self.def_id), let generics = (cx.tcx.generics_of(self.def_id),
&cx.tcx.predicates_of(self.def_id)).clean(cx); &cx.tcx.predicates_of(self.def_id)).clean(cx);
let sig = cx.tcx.type_of(self.def_id).fn_sig(); let sig = cx.tcx.fn_sig(self.def_id);
let mut decl = (self.def_id, sig).clean(cx); let mut decl = (self.def_id, sig).clean(cx);
if self.method_has_self_argument { if self.method_has_self_argument {
@ -1842,17 +1842,21 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
mutability: mt.mutbl.clean(cx), mutability: mt.mutbl.clean(cx),
type_: box mt.ty.clean(cx), type_: box mt.ty.clean(cx),
}, },
ty::TyFnDef(.., sig) | ty::TyFnDef(..) |
ty::TyFnPtr(sig) => BareFunction(box BareFunctionDecl { ty::TyFnPtr(_) => {
unsafety: sig.unsafety(), let ty = cx.tcx.lift(self).unwrap();
generics: Generics { let sig = ty.fn_sig(cx.tcx);
lifetimes: Vec::new(), BareFunction(box BareFunctionDecl {
type_params: Vec::new(), unsafety: sig.unsafety(),
where_predicates: Vec::new() generics: Generics {
}, lifetimes: Vec::new(),
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx), type_params: Vec::new(),
abi: sig.abi(), where_predicates: Vec::new()
}), },
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
abi: sig.abi(),
})
}
ty::TyAdt(def, substs) => { ty::TyAdt(def, substs) => {
let did = def.did; let did = def.did;
let kind = match def.adt_kind() { let kind = match def.adt_kind() {

View File

@ -11,6 +11,6 @@
#![feature(intrinsics)] #![feature(intrinsics)]
extern "rust-intrinsic" { extern "rust-intrinsic" {
pub static breakpoint : unsafe extern "rust-intrinsic" fn(); pub static breakpoint : unsafe extern "rust-intrinsic" fn();
//~^ ERROR intrinsic has wrong type //~^ ERROR intrinsic must be a function
} }
fn main() { unsafe { breakpoint(); } } fn main() { unsafe { breakpoint(); } }