mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
rustc: move the PolyFnSig out of TyFnDef.
This commit is contained in:
parent
8e53a03d15
commit
33ecf72e8e
@ -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);
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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>(
|
||||
|
@ -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,
|
||||
|
@ -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> {
|
||||
|
@ -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(_) => {
|
||||
|
@ -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) => {
|
||||
|
@ -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 |
|
||||
|
@ -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 => {
|
||||
|
@ -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)) =>
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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, "}}")
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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]
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 ");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
_ => {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 ");
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 => {
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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(); } }
|
||||
|
Loading…
Reference in New Issue
Block a user