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);
pointee_ty.hash_stable(hcx, hasher);
}
TyFnDef(def_id, substs, ref sig) => {
TyFnDef(def_id, substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
sig.hash_stable(hcx, hasher);
}
TyFnPtr(ref sig) => {
sig.hash_stable(hcx, hasher);

View File

@ -12,7 +12,7 @@
//! `unsafe`.
use self::RootUnsafeContext::*;
use ty::{self, Ty, TyCtxt};
use ty::{self, TyCtxt};
use lint;
use syntax::ast;
@ -40,14 +40,6 @@ enum RootUnsafeContext {
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> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
@ -174,10 +166,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
match expr.node {
hir::ExprMethodCall(..) => {
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
let base_type = self.tcx.type_of(def_id);
debug!("effect: method call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
let sig = self.tcx.fn_sig(def_id);
debug!("effect: method call case, signature is {:?}",
sig);
if sig.0.unsafety == hir::Unsafety::Unsafe {
self.require_unsafe(expr.span,
"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);
debug!("effect: call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
self.require_unsafe(expr.span, "call to unsafe function")
match base_type.sty {
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) => {

View File

@ -66,11 +66,8 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
let intrinsic = match self.tcx.type_of(def_id).sty {
ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic,
_ => return false
};
intrinsic && self.tcx.item_name(def_id) == "transmute"
self.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
self.tcx.item_name(def_id) == "transmute"
}
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 {
Def::Err
};
match def {
Def::Fn(did) if self.def_id_is_transmute(did) => {
if let Def::Fn(did) = def {
if self.def_id_is_transmute(did) {
let typ = self.tables.node_id_to_type(expr.id);
let typ = self.tcx.lift_to_global(&typ).unwrap();
match typ.sty {
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);
}
_ => {
span_bug!(expr.span, "transmute wasn't a bare fn?!");
}
}
let sig = typ.fn_sig(self.tcx);
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();
self.check_transmute(expr.span, from, to);
}
_ => {}
}
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
// 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..] {
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
return Some(MethodViolationCode::ReferencesSelf);

View File

@ -1137,9 +1137,19 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
-> Progress<'tcx>
{
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)
.with_addl_obligations(fn_pointer_vtable.nested)
.with_addl_obligations(obligations)
}
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
ty::TyFnDef(.., ty::Binder(ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
variadic: false,
..
})) |
ty::TyFnPtr(ty::Binder(ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
variadic: false,
..
})) => {
candidates.vec.push(FnPointerCandidate);
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
if let ty::Binder(ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
variadic: false,
..
}) = self_ty.fn_sig(self.tcx()) {
candidates.vec.push(FnPointerCandidate);
}
}
_ => { }
@ -2348,7 +2344,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// ok to skip binder; it is reintroduced below
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 =
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
self_ty,
@ -2356,11 +2352,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
util::TupleArgumentsFlag::Yes)
.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(),
obligation.param_env,
obligation.predicate.to_poly_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,

View File

@ -1378,9 +1378,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
pub fn mk_fn_def(self, def_id: DefId,
substs: &'tcx Substs<'tcx>,
fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnDef(def_id, substs, fty))
substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnDef(def_id, substs))
}
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
simplify_type(tcx, mt.ty, can_simplify_params)
}
ty::TyFnDef(def_id, _) |
ty::TyClosure(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, _) => {
Some(TupleSimplifiedType(tys.len()))
}
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {
ty::TyFnPtr(ref f) => {
Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
}
ty::TyProjection(_) | ty::TyParam(_) => {

View File

@ -155,9 +155,8 @@ impl FlagComputation {
self.add_tys(&ts[..]);
}
&ty::TyFnDef(_, substs, f) => {
&ty::TyFnDef(_, substs) => {
self.add_substs(substs);
self.add_fn_sig(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))
.next(),
ty::TyFnDef(def_id, ..) |
ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) => Some(def_id),
ty::TyBool |

View File

@ -206,7 +206,7 @@ impl AssociatedItem {
// late-bound regions, and we don't want method signatures to show up
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
// 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::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(b_def_id, b_substs, b_fty))
(&ty::TyFnDef(a_def_id, a_substs), &ty::TyFnDef(b_def_id, b_substs))
if a_def_id == b_def_id =>
{
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, fty))
Ok(tcx.mk_fn_def(a_def_id, substs))
}
(&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(trait_ty.fold_with(folder), region.fold_with(folder)),
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
ty::TyFnDef(def_id, substs, f) => {
ty::TyFnDef(def_id,
substs.fold_with(folder),
f.fold_with(folder))
ty::TyFnDef(def_id, substs) => {
ty::TyFnDef(def_id, substs.fold_with(folder))
}
ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
ty::TyRef(ref r, tm) => {
@ -568,9 +566,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyDynamic(ref trait_ty, ref reg) =>
trait_ty.visit_with(visitor) || reg.visit_with(visitor),
ty::TyTuple(ts, _) => ts.visit_with(visitor),
ty::TyFnDef(_, substs, ref f) => {
substs.visit_with(visitor) || f.visit_with(visitor)
}
ty::TyFnDef(_, substs) => substs.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::TyClosure(_did, ref substs) => substs.visit_with(visitor),

View File

@ -14,7 +14,7 @@ use hir::def_id::DefId;
use hir::map::DefPathHash;
use middle::region;
use ty::subst::Substs;
use ty::subst::{Substs, Subst};
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
use ty::{Slice, TyS};
use ty::subst::Kind;
@ -138,7 +138,7 @@ pub enum TypeVariants<'tcx> {
/// The anonymous type of a function declaration/definition. Each
/// 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`.
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 {
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)
}
}

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),
TyClosure(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),
TyFnPtr(f) => {
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, _) => {
stack.extend(ts.iter().cloned().rev());
}
ty::TyFnDef(_, substs, ft) => {
ty::TyFnDef(_, substs) => {
stack.extend(substs.types().rev());
push_sig_subtypes(stack, ft);
}
ty::TyFnPtr(ft) => {
push_sig_subtypes(stack, ft);

View File

@ -753,8 +753,14 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
}
write!(f, ")")
}
TyFnDef(def_id, substs, ref bare_fn) => {
write!(f, "{} {{", bare_fn.0)?;
TyFnDef(def_id, substs) => {
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, &[])?;
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>>)
-> Option<(&'a [mir::Operand<'tcx>], Span)> {
if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
{
if let mir::Operand::Constant(ref func) = *oper
{
if let ty::TyFnDef(def_id, _, sig) = func.ty.sty
{
let abi = sig.abi();
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind {
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();
let name = tcx.item_name(def_id);
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
if name == "rustc_peek" {
return Some((args, source_info.span));
}
if abi == Abi::RustIntrinsic && name == "rustc_peek" {
return Some((args, source_info.span));
}
}
}

View File

@ -12,7 +12,7 @@ use eval;
use rustc::middle::const_val::{ConstEvalErr, ConstVal};
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::hir::{self, PatKind, RangeEnd};
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);
if adt_def.variants.len() > 1 {
let substs = match ty.sty {
TypeVariants::TyAdt(_, substs) => substs,
TypeVariants::TyFnDef(_, substs, _) => substs,
ty::TyAdt(_, substs) |
ty::TyFnDef(_, substs) => substs,
_ => bug!("inappropriate type for def: {:?}", ty.sty),
};
PatternKind::Variant {

View File

@ -1154,24 +1154,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
if !def_id_is_transmute(cx, did) {
return None;
}
let typ = cx.tables.node_id_to_type(expr.id);
match typ.sty {
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));
}
_ => (),
}
let sig = cx.tables.node_id_to_type(expr.id).fn_sig(cx.tcx);
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();
return Some((&from.sty, &to.sty));
}
None
}
fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool {
match cx.tcx.type_of(def_id).sty {
ty::TyFnDef(.., bfty) if bfty.abi() == RustIntrinsic => (),
_ => return false,
}
cx.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
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) {
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);
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,
closure_id: DefIndex,
id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::PolyFnSig<'tcx> {
match self.entry(closure_id).kind {
EntryKind::Closure(data) => data.decode(self).sig.decode((self, tcx)),
let sig = match self.entry(id).kind {
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!(),
}
};
sig.decode((self, tcx))
}
#[inline]

View File

@ -16,6 +16,7 @@ use schema::*;
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
EncodedMetadata, EncodedMetadataHashes,
EncodedMetadataHash};
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::ich::Fingerprint;
@ -499,6 +500,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
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();
@ -617,6 +623,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
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();
@ -695,7 +706,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
};
FnData {
constness: hir::Constness::NotConst,
arg_names: arg_names
arg_names: arg_names,
sig: self.lazy(&tcx.fn_sig(def_id)),
}
} else {
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> {
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 ast_item = self.tcx.hir.expect_impl_item(node_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 {
constness: sig.constness,
arg_names: self.encode_fn_arg_names_for_body(body),
sig: self.lazy(&tcx.fn_sig(def_id)),
}
} else {
bug!()
@ -881,6 +896,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
let data = FnData {
constness: constness,
arg_names: self.encode_fn_arg_names_for_body(body),
sig: self.lazy(&tcx.fn_sig(def_id)),
};
EntryKind::Fn(self.lazy(&data))
@ -910,6 +926,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
struct_ctor: struct_ctor,
ctor_sig: None,
}), repr_options)
}
hir::ItemUnion(..) => {
@ -920,6 +937,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
struct_ctor: None,
ctor_sig: None,
}), repr_options)
}
hir::ItemDefaultImpl(..) => {
@ -1363,6 +1381,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
let data = FnData {
constness: hir::Constness::NotConst,
arg_names: self.encode_fn_arg_names(names),
sig: self.lazy(&tcx.fn_sig(def_id)),
};
EntryKind::ForeignFn(self.lazy(&data))
}

View File

@ -343,18 +343,18 @@ pub enum EntryKind<'tcx> {
Type,
Enum(ReprOptions),
Field,
Variant(Lazy<VariantData>),
Struct(Lazy<VariantData>, ReprOptions),
Union(Lazy<VariantData>, ReprOptions),
Fn(Lazy<FnData>),
ForeignFn(Lazy<FnData>),
Variant(Lazy<VariantData<'tcx>>),
Struct(Lazy<VariantData<'tcx>>, ReprOptions),
Union(Lazy<VariantData<'tcx>>, ReprOptions),
Fn(Lazy<FnData<'tcx>>),
ForeignFn(Lazy<FnData<'tcx>>),
Mod(Lazy<ModData>),
MacroDef(Lazy<MacroDef>),
Closure(Lazy<ClosureData<'tcx>>),
Trait(Lazy<TraitData<'tcx>>),
Impl(Lazy<ImplData<'tcx>>),
DefaultImpl(Lazy<ImplData<'tcx>>),
Method(Lazy<MethodData>),
Method(Lazy<MethodData<'tcx>>),
AssociatedType(AssociatedContainer),
AssociatedConst(AssociatedContainer, u8),
}
@ -439,27 +439,33 @@ pub struct MacroDef {
impl_stable_hash_for!(struct MacroDef { body, legacy });
#[derive(RustcEncodable, RustcDecodable)]
pub struct FnData {
pub struct FnData<'tcx> {
pub constness: hir::Constness,
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)]
pub struct VariantData {
pub struct VariantData<'tcx> {
pub ctor_kind: CtorKind,
pub discr: ty::VariantDiscr,
/// If this is a struct's only variant, this
/// is the index of the "struct ctor" item.
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,
discr,
struct_ctor
struct_ctor,
ctor_sig
});
#[derive(RustcEncodable, RustcDecodable)]
@ -543,12 +549,12 @@ impl AssociatedContainer {
}
#[derive(RustcEncodable, RustcDecodable)]
pub struct MethodData {
pub fn_data: FnData,
pub struct MethodData<'tcx> {
pub fn_data: FnData<'tcx>,
pub container: AssociatedContainer,
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)]
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
let diverges = expr.ty.is_never();
let intrinsic = match ty.sty {
ty::TyFnDef(def_id, _, ref f) if
f.abi() == Abi::RustIntrinsic ||
f.abi() == Abi::PlatformIntrinsic =>
{
Some(this.hir.tcx().item_name(def_id).as_str())
ty::TyFnDef(def_id, _) => {
let f = ty.fn_sig(this.hir.tcx());
if f.abi() == Abi::RustIntrinsic ||
f.abi() == Abi::PlatformIntrinsic {
Some(this.hir.tcx().item_name(def_id).as_str())
} else {
None
}
}
_ => None
};

View File

@ -19,7 +19,6 @@ use rustc::middle::const_val::ConstVal;
use rustc::ty::{self, AdtKind, VariantDef, Ty};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
use rustc::ty::cast::CastKind as TyCastKind;
use rustc::ty::subst::Subst;
use rustc::hir;
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 {
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,
kind: ExprKind::Literal {
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
// the param-substs, but because they are concrete, this
// 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();
build_call_shim(
@ -153,8 +153,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
} else {
Substs::identity_for_item(tcx, def_id)
};
let fn_ty = tcx.type_of(def_id).subst(tcx, substs);
let sig = tcx.erase_late_bound_regions(&fn_ty.fn_sig());
let sig = tcx.fn_sig(def_id).subst(tcx, substs);
let sig = tcx.erase_late_bound_regions(&sig);
let span = tcx.def_span(def_id);
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={:?})",
def_id, rcvr_adjustment, call_kind, untuple_args);
let fn_ty = tcx.type_of(def_id);
let sig = tcx.erase_late_bound_regions(&fn_ty.fn_sig());
let sig = tcx.fn_sig(def_id);
let sig = tcx.erase_late_bound_regions(&sig);
let span = tcx.def_span(def_id);
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 def_id = tcx.hir.local_def_id(ctor_id);
let sig = match tcx.type_of(def_id).sty {
ty::TyFnDef(_, _, fty) => tcx.no_late_bound_regions(&fty)
.expect("LBR in ADT constructor signature"),
_ => bug!("unexpected type for ctor {:?}", def_id)
};
let sig = tcx.no_late_bound_regions(&tcx.fn_sig(def_id))
.expect("LBR in ADT constructor signature");
let sig = tcx.erase_regions(&sig);
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();
if let TerminatorKind::Call {
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 {
callee: callee_def_id,
substs: substs,
@ -131,7 +131,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let terminator = bb_data.terminator();
if let TerminatorKind::Call {
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.
if callsite.callee != callee_def_id {
callsites.push_back(CallSite {
@ -270,8 +270,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
}
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
let f = tcx.fn_sig(def_id);
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
cost += INSTR_COST;
} 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 (is_shuffle, is_const_fn) = match fn_ty.sty {
ty::TyFnDef(def_id, _, f) => {
(f.abi() == Abi::PlatformIntrinsic &&
ty::TyFnDef(def_id, _) => {
(self.tcx.fn_sig(def_id).abi() == Abi::PlatformIntrinsic &&
self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
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);
debug!("check_terminator: call, func_ty={:?}", func_ty);
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);
return;

View File

@ -400,7 +400,13 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
}
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
}
@ -910,7 +916,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
}
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
}

View File

@ -154,6 +154,13 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
assert!(!item_type.has_erasable_regions());
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)
if let Some(substs) = substs {
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,
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);
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>
{
match ty.sty {
ty::TyFnDef(_, _, sig) => sig,
ty::TyFnDef(..) |
// 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) => {
let tcx = ccx.tcx();
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);
let sty = &t.sty;
let ptr_metadata = |ty: Ty<'tcx>| {
match ty.sty {
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::TyBool |
ty::TyChar |
@ -557,10 +556,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
Err(metadata) => return metadata,
}
}
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => {
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let fn_metadata = subroutine_type_metadata(cx,
unique_type_id,
sig,
t.fn_sig(cx.tcx()),
usage_site_span).metadata;
match debug_context(cx).type_map
.borrow()
@ -610,7 +609,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
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);
}
},
ty::TyFnDef(.., sig) |
ty::TyFnPtr(sig) => {
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
let sig = t.fn_sig(cx.tcx());
if sig.unsafety() == hir::Unsafety::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 tcx = ccx.tcx();
let (def_id, substs, sig) = match callee_ty.sty {
ty::TyFnDef(def_id, substs, sig) => (def_id, substs, sig),
let (def_id, substs) = match callee_ty.sty {
ty::TyFnDef(def_id, substs) => (def_id, substs),
_ => 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 arg_tys = sig.inputs();
let ret_ty = sig.output();
@ -986,7 +987,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
let tcx = bcx.tcx();
let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig());
let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig(tcx));
let arg_tys = sig.inputs();
// 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.
let callee = self.trans_operand(&bcx, func);
let (instance, mut llfn, sig) = match callee.ty.sty {
ty::TyFnDef(def_id, substs, sig) => {
let (instance, mut llfn) = match callee.ty.sty {
ty::TyFnDef(def_id, substs) => {
(Some(monomorphize::resolve(bcx.ccx.shared(), def_id, substs)),
None,
sig)
None)
}
ty::TyFnPtr(sig) => {
(None,
Some(callee.immediate()),
sig)
ty::TyFnPtr(_) => {
(None, Some(callee.immediate()))
}
_ => bug!("{} is not callable", callee.ty)
};
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 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 = self.monomorphize(&fn_ty);
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",
func, fn_ty)
};
@ -560,7 +560,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let val = match *kind {
mir::CastKind::ReifyFnPointer => {
match operand.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
ty::TyFnDef(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 {
mir::CastKind::ReifyFnPointer => {
match operand.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
ty::TyFnDef(def_id, substs) => {
OperandValue::Immediate(
callee::resolve_and_get_fn(bcx.ccx, def_id, substs))
}

View File

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

View File

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

View File

@ -619,7 +619,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Type check the path.
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.
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");
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>)
-> Ty<'tcx> {
let (fn_sig, def_span) = match callee_ty.sty {
ty::TyFnDef(def_id, .., sig) => {
(sig, self.tcx.hir.span_if_local(def_id))
ty::TyFnDef(def_id, _) => {
(callee_ty.fn_sig(self.tcx), self.tcx.hir.span_if_local(def_id))
}
ty::TyFnPtr(sig) => (sig, None),
ref t => {

View File

@ -356,8 +356,9 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
// Function item types may need to be reified before casts.
(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.
let f = self.expr_ty.fn_sig(fcx.tcx);
let res = fcx.try_coerce(self.expr,
self.expr_ty,
self.expr_diverges,

View File

@ -210,13 +210,13 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
}
match a.sty {
ty::TyFnDef(.., a_f) => {
ty::TyFnDef(..) => {
// Function items are coercible to any closure
// type; function pointers are not (that would
// require double indirection).
// Additionally, we permit coercion of function
// 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) => {
// 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,
a: Ty<'tcx>,
fn_ty_a: ty::PolyFnSig<'tcx>,
b: Ty<'tcx>)
-> CoerceResult<'tcx> {
//! 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 {
ty::TyFnPtr(_) => {
let a_fn_pointer = self.tcx.mk_fn_ptr(fn_ty_a);
self.coerce_from_safe_fn(a_fn_pointer, fn_ty_a, b,
simple(Adjust::ReifyFnPointer), simple(Adjust::ReifyFnPointer))
let a_sig = a.fn_sig(self.tcx);
let InferOk { value: a_sig, mut obligations } =
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),
}
@ -775,42 +782,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Special-case that coercion alone cannot handle:
// Two function item types of differing IDs or Substs.
match (&prev_ty.sty, &new_ty.sty) {
(&ty::TyFnDef(a_def_id, a_substs, a_fty), &ty::TyFnDef(b_def_id, b_substs, b_fty)) => {
// The signature must always match.
let fty = self.at(cause, self.param_env)
.trace(prev_ty, new_ty)
.lub(&a_fty, &b_fty)
.map(|ok| self.register_infer_ok_obligations(ok))?;
if let (&ty::TyFnDef(..), &ty::TyFnDef(..)) = (&prev_ty.sty, &new_ty.sty) {
// Don't reify if the function types have a LUB, i.e. they
// are the same function and their parameters have a LUB.
let lub_ty = self.commit_if_ok(|_| {
self.at(cause, self.param_env)
.lub(prev_ty, new_ty)
.map(|ok| self.register_infer_ok_obligations(ok))
});
if a_def_id == b_def_id {
// Same function, maybe the parameters match.
let substs = self.commit_if_ok(|_| {
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);
if lub_ty.is_ok() {
// We have a LUB of prev_ty and new_ty, just return it.
return lub_ty;
}
_ => {}
// 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());

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.
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, _) =
infcx.replace_late_bound_regions_with_fresh_var(impl_m_span,
infer::HigherRankedType,
&m_sig(impl_m));
&tcx.fn_sig(impl_m.def_id));
let impl_sig =
inh.normalize_associated_types_in(impl_m_span,
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(
impl_m.def_id,
&m_sig(trait_m));
&tcx.fn_sig(trait_m.def_id));
let trait_sig =
trait_sig.subst(tcx, trait_to_skol_substs);
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::TraitContainer(_) => tcx.mk_self_type()
};
let method_ty = tcx.type_of(method.def_id);
let self_arg_ty = *method_ty.fn_sig().input(0).skip_binder();
let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
match ExplicitSelf::determine(untransformed_self_ty, self_arg_ty) {
ExplicitSelf::ByValue => "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_item_span: Option<Span>)
-> Result<(), ErrorReported> {
let m_fty = |method: &ty::AssociatedItem| {
match tcx.type_of(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_m_fty = tcx.fn_sig(impl_m.def_id);
let trait_m_fty = tcx.fn_sig(trait_m.def_id);
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 {

View File

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

View File

@ -13,7 +13,6 @@
use intrinsics;
use rustc::traits::{ObligationCause, ObligationCauseCode};
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt, Ty};
use rustc::util::nodemap::FxHashMap;
use require_same_types;
@ -35,22 +34,22 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
output: Ty<'tcx>) {
let def_id = tcx.hir.local_def_id(it.id);
let substs = Substs::for_item(tcx, def_id,
|_, _| tcx.types.re_erased,
|def, _| tcx.mk_param_from_def(def));
match it.node {
hir::ForeignItemFn(..) => {}
_ => {
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();
if i_n_tps != n_tps {
let span = match it.node {
hir::ForeignItemFn(_, _, ref generics) => generics.span,
hir::ForeignItemStatic(..) => it.span
_ => bug!()
};
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)
.span_label(span, format!("expected {} type parameter", n_tps))
.emit();
} else {
require_same_types(tcx,
&ObligationCause::new(it.span,
it.id,
ObligationCauseCode::IntrinsicType),
tcx.type_of(def_id),
fty);
return;
}
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,
@ -376,7 +379,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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();
if intr.inputs.len() != sig.inputs().len() {
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);
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
// 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
// `instantiate_type_scheme` can normalize associated types that
// 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,
infer::FnCall,
&fn_sig).0;

View File

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

View File

@ -718,20 +718,12 @@ pub fn provide(providers: &mut Providers) {
typeck_item_bodies,
typeck_tables_of,
has_typeck_tables,
fn_sig,
closure_kind,
adt_destructor,
..*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>,
def_id: DefId)
-> ty::ClosureKind {
@ -844,7 +836,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Inherited::build(tcx, def_id).enter(|inh| {
let param_env = tcx.param_env(def_id);
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());
@ -2173,7 +2165,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-> ty::TypeAndMut<'tcx>
{
// extract method return type, which will be &T;
// all LB regions should have been instantiated during method lookup
let ret_ty = method.sig.output();
// 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) => {
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
}
ty::TyFnDef(.., f) => {
let ptr_ty = self.tcx.mk_fn_ptr(f);
ty::TyFnDef(..) => {
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);
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 => {
reject_shadowing_type_parameters(fcx.tcx, item.def_id);
let method_ty = fcx.tcx.type_of(item.def_id);
let method_ty = fcx.normalize_associated_types_in(span, &method_ty);
let sig = fcx.tcx.fn_sig(item.def_id);
let sig = fcx.normalize_associated_types_in(span, &sig);
let predicates = fcx.tcx.predicates_of(item.def_id)
.instantiate_identity(fcx.tcx);
let predicates = fcx.normalize_associated_types_in(span, &predicates);
let sig = method_ty.fn_sig();
this.check_fn_or_method(fcx, span, sig, &predicates,
item.def_id, &mut implied_bounds);
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) {
self.for_item(item).with_fcx(|fcx, this| {
let def_id = fcx.tcx.hir.local_def_id(item.id);
let ty = fcx.tcx.type_of(def_id);
let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
let sig = item_ty.fn_sig();
let sig = fcx.tcx.fn_sig(def_id);
let sig = fcx.normalize_associated_types_in(item.span, &sig);
let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx);
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 method_ty = fcx.tcx.type_of(method.def_id);
let fty = fcx.normalize_associated_types_in(span, &method_ty);
let sig = fcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig());
let sig = fcx.tcx.fn_sig(method.def_id);
let sig = fcx.normalize_associated_types_in(span, &sig);
let sig = fcx.liberate_late_bound_regions(method.def_id, &sig);
debug!("check_method_receiver: sig={:?}", sig);

View File

@ -97,6 +97,7 @@ pub fn provide(providers: &mut Providers) {
type_param_predicates,
trait_def,
adt_def,
fn_sig,
impl_trait_ref,
impl_polarity,
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.type_of(def_id);
tcx.predicates_of(def_id);
if let hir::ForeignItemFn(..) = item.node {
tcx.fn_sig(def_id);
}
}
}
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.type_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::Method(..) => {
tcx.type_of(def_id);
if let hir::TraitItemKind::Method(..) = trait_item.node {
tcx.fn_sig(def_id);
}
}
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.type_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>,
@ -963,10 +976,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
match tcx.hir.get(node_id) {
NodeTraitItem(item) => {
match item.node {
TraitItemKind::Method(ref sig, _) => {
let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
TraitItemKind::Method(..) => {
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::Type(_, Some(ref ty)) => icx.to_ty(ty),
@ -978,10 +990,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
NodeImplItem(item) => {
match item.node {
ImplItemKind::Method(ref sig, _) => {
let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
ImplItemKind::Method(..) => {
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::Type(ref ty) => {
@ -1001,10 +1012,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
icx.to_ty(t)
}
ItemFn(ref decl, unsafety, _, abi, _, _) => {
let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl);
ItemFn(..) => {
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(..) |
ItemStruct(..) |
@ -1029,11 +1039,10 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
NodeForeignItem(foreign_item) => {
let abi = tcx.hir.get_foreign_abi(node_id);
match foreign_item.node {
ForeignItemFn(ref fn_decl, _, _) => {
compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
ForeignItemFn(..) => {
let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs)
}
ForeignItemStatic(ref t, _) => icx.to_ty(t)
}
@ -1041,21 +1050,13 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
NodeStructCtor(&ref def) |
NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
match *def {
VariantData::Unit(..) | VariantData::Struct(..) => ty,
VariantData::Tuple(ref fields, _) => {
let inputs = fields.iter().map(|f| {
tcx.type_of(tcx.hir.local_def_id(f.id))
});
VariantData::Unit(..) | VariantData::Struct(..) => {
tcx.type_of(tcx.hir.get_parent_did(node_id))
}
VariantData::Tuple(..) => {
let substs = Substs::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
inputs,
ty,
false,
hir::Unsafety::Normal,
abi::Abi::Rust
)))
tcx.mk_fn_def(def_id, substs)
}
}
}
@ -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>,
def_id: DefId)
-> 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>,
def_id: DefId,
decl: &hir::FnDecl,
abi: abi::Abi)
-> Ty<'tcx>
-> ty::PolyFnSig<'tcx>
{
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);
tcx.mk_fn_def(def_id, substs, fty)
fty
}
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,
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
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_def(main_def_id, substs,
ty::Binder(tcx.mk_fn_sig(
let se_ty = tcx.mk_fn_ptr(ty::Binder(
tcx.mk_fn_sig(
iter::empty(),
tcx.mk_nil(),
false,
hir::Unsafety::Normal,
Abi::Rust
))
);
)
));
require_same_types(
tcx,
&ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
se_ty,
main_t);
tcx.mk_fn_ptr(tcx.fn_sig(main_def_id)));
}
_ => {
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_def(start_def_id, substs,
ty::Binder(tcx.mk_fn_sig(
let se_ty = tcx.mk_fn_ptr(ty::Binder(
tcx.mk_fn_sig(
[
tcx.types.isize,
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,
hir::Unsafety::Normal,
Abi::Rust
))
);
)
));
require_same_types(
tcx,
&ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
se_ty,
start_t);
tcx.mk_fn_ptr(tcx.fn_sig(start_def_id)));
}
_ => {
span_bug!(start_span,

View File

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

View File

@ -1367,7 +1367,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
ty::AssociatedKind::Method => {
let generics = (cx.tcx.generics_of(self.def_id),
&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);
if self.method_has_self_argument {
@ -1842,17 +1842,21 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
mutability: mt.mutbl.clean(cx),
type_: box mt.ty.clean(cx),
},
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), sig).clean(cx),
abi: sig.abi(),
}),
ty::TyFnDef(..) |
ty::TyFnPtr(_) => {
let ty = cx.tcx.lift(self).unwrap();
let sig = ty.fn_sig(cx.tcx);
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), sig).clean(cx),
abi: sig.abi(),
})
}
ty::TyAdt(def, substs) => {
let did = def.did;
let kind = match def.adt_kind() {

View File

@ -11,6 +11,6 @@
#![feature(intrinsics)]
extern "rust-intrinsic" {
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(); } }