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);
|
region.hash_stable(hcx, hasher);
|
||||||
pointee_ty.hash_stable(hcx, hasher);
|
pointee_ty.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
TyFnDef(def_id, substs, ref sig) => {
|
TyFnDef(def_id, substs) => {
|
||||||
def_id.hash_stable(hcx, hasher);
|
def_id.hash_stable(hcx, hasher);
|
||||||
substs.hash_stable(hcx, hasher);
|
substs.hash_stable(hcx, hasher);
|
||||||
sig.hash_stable(hcx, hasher);
|
|
||||||
}
|
}
|
||||||
TyFnPtr(ref sig) => {
|
TyFnPtr(ref sig) => {
|
||||||
sig.hash_stable(hcx, hasher);
|
sig.hash_stable(hcx, hasher);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
//! `unsafe`.
|
//! `unsafe`.
|
||||||
use self::RootUnsafeContext::*;
|
use self::RootUnsafeContext::*;
|
||||||
|
|
||||||
use ty::{self, Ty, TyCtxt};
|
use ty::{self, TyCtxt};
|
||||||
use lint;
|
use lint;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
@ -40,14 +40,6 @@ enum RootUnsafeContext {
|
|||||||
UnsafeBlock(ast::NodeId),
|
UnsafeBlock(ast::NodeId),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_is_unsafe_function(ty: Ty) -> bool {
|
|
||||||
match ty.sty {
|
|
||||||
ty::TyFnDef(.., f) |
|
|
||||||
ty::TyFnPtr(f) => f.unsafety() == hir::Unsafety::Unsafe,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EffectCheckVisitor<'a, 'tcx: 'a> {
|
struct EffectCheckVisitor<'a, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
tables: &'a ty::TypeckTables<'tcx>,
|
||||||
@ -174,10 +166,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
|
|||||||
match expr.node {
|
match expr.node {
|
||||||
hir::ExprMethodCall(..) => {
|
hir::ExprMethodCall(..) => {
|
||||||
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
|
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
|
||||||
let base_type = self.tcx.type_of(def_id);
|
let sig = self.tcx.fn_sig(def_id);
|
||||||
debug!("effect: method call case, base type is {:?}",
|
debug!("effect: method call case, signature is {:?}",
|
||||||
base_type);
|
sig);
|
||||||
if type_is_unsafe_function(base_type) {
|
|
||||||
|
if sig.0.unsafety == hir::Unsafety::Unsafe {
|
||||||
self.require_unsafe(expr.span,
|
self.require_unsafe(expr.span,
|
||||||
"invocation of unsafe method")
|
"invocation of unsafe method")
|
||||||
}
|
}
|
||||||
@ -186,8 +179,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
|
|||||||
let base_type = self.tables.expr_ty_adjusted(base);
|
let base_type = self.tables.expr_ty_adjusted(base);
|
||||||
debug!("effect: call case, base type is {:?}",
|
debug!("effect: call case, base type is {:?}",
|
||||||
base_type);
|
base_type);
|
||||||
if type_is_unsafe_function(base_type) {
|
match base_type.sty {
|
||||||
self.require_unsafe(expr.span, "call to unsafe function")
|
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||||
|
if base_type.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
|
||||||
|
self.require_unsafe(expr.span, "call to unsafe function")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprUnary(hir::UnDeref, ref base) => {
|
hir::ExprUnary(hir::UnDeref, ref base) => {
|
||||||
|
@ -66,11 +66,8 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
|
||||||
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
|
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
|
||||||
let intrinsic = match self.tcx.type_of(def_id).sty {
|
self.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
|
||||||
ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic,
|
self.tcx.item_name(def_id) == "transmute"
|
||||||
_ => return false
|
|
||||||
};
|
|
||||||
intrinsic && self.tcx.item_name(def_id) == "transmute"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
|
fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
|
||||||
@ -153,22 +150,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
Def::Err
|
Def::Err
|
||||||
};
|
};
|
||||||
match def {
|
if let Def::Fn(did) = def {
|
||||||
Def::Fn(did) if self.def_id_is_transmute(did) => {
|
if self.def_id_is_transmute(did) {
|
||||||
let typ = self.tables.node_id_to_type(expr.id);
|
let typ = self.tables.node_id_to_type(expr.id);
|
||||||
let typ = self.tcx.lift_to_global(&typ).unwrap();
|
let sig = typ.fn_sig(self.tcx);
|
||||||
match typ.sty {
|
let from = sig.inputs().skip_binder()[0];
|
||||||
ty::TyFnDef(.., sig) if sig.abi() == RustIntrinsic => {
|
let to = *sig.output().skip_binder();
|
||||||
let from = sig.inputs().skip_binder()[0];
|
self.check_transmute(expr.span, from, to);
|
||||||
let to = *sig.output().skip_binder();
|
|
||||||
self.check_transmute(expr.span, from, to);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
span_bug!(expr.span, "transmute wasn't a bare fn?!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intravisit::walk_expr(self, expr);
|
intravisit::walk_expr(self, expr);
|
||||||
|
@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// The `Self` type is erased, so it should not appear in list of
|
// The `Self` type is erased, so it should not appear in list of
|
||||||
// arguments or return type apart from the receiver.
|
// arguments or return type apart from the receiver.
|
||||||
let ref sig = self.type_of(method.def_id).fn_sig();
|
let ref sig = self.fn_sig(method.def_id);
|
||||||
for input_ty in &sig.skip_binder().inputs()[1..] {
|
for input_ty in &sig.skip_binder().inputs()[1..] {
|
||||||
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
|
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
|
||||||
return Some(MethodViolationCode::ReferencesSelf);
|
return Some(MethodViolationCode::ReferencesSelf);
|
||||||
|
@ -1137,9 +1137,19 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
|
|||||||
-> Progress<'tcx>
|
-> Progress<'tcx>
|
||||||
{
|
{
|
||||||
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
|
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
|
||||||
let sig = fn_type.fn_sig();
|
let sig = fn_type.fn_sig(selcx.tcx());
|
||||||
|
let Normalized {
|
||||||
|
value: sig,
|
||||||
|
obligations
|
||||||
|
} = normalize_with_depth(selcx,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth+1,
|
||||||
|
&sig);
|
||||||
|
|
||||||
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
|
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
|
||||||
.with_addl_obligations(fn_pointer_vtable.nested)
|
.with_addl_obligations(fn_pointer_vtable.nested)
|
||||||
|
.with_addl_obligations(obligations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
|
fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
|
||||||
|
@ -1404,19 +1404,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// provide an impl, but only for suitable `fn` pointers
|
// provide an impl, but only for suitable `fn` pointers
|
||||||
ty::TyFnDef(.., ty::Binder(ty::FnSig {
|
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||||
unsafety: hir::Unsafety::Normal,
|
if let ty::Binder(ty::FnSig {
|
||||||
abi: Abi::Rust,
|
unsafety: hir::Unsafety::Normal,
|
||||||
variadic: false,
|
abi: Abi::Rust,
|
||||||
..
|
variadic: false,
|
||||||
})) |
|
..
|
||||||
ty::TyFnPtr(ty::Binder(ty::FnSig {
|
}) = self_ty.fn_sig(self.tcx()) {
|
||||||
unsafety: hir::Unsafety::Normal,
|
candidates.vec.push(FnPointerCandidate);
|
||||||
abi: Abi::Rust,
|
}
|
||||||
variadic: false,
|
|
||||||
..
|
|
||||||
})) => {
|
|
||||||
candidates.vec.push(FnPointerCandidate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => { }
|
_ => { }
|
||||||
@ -2348,7 +2344,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// ok to skip binder; it is reintroduced below
|
// ok to skip binder; it is reintroduced below
|
||||||
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
let sig = self_ty.fn_sig();
|
let sig = self_ty.fn_sig(self.tcx());
|
||||||
let trait_ref =
|
let trait_ref =
|
||||||
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
|
||||||
self_ty,
|
self_ty,
|
||||||
@ -2356,11 +2352,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
util::TupleArgumentsFlag::Yes)
|
util::TupleArgumentsFlag::Yes)
|
||||||
.map_bound(|(trait_ref, _)| trait_ref);
|
.map_bound(|(trait_ref, _)| trait_ref);
|
||||||
|
|
||||||
|
let Normalized { value: trait_ref, obligations } =
|
||||||
|
project::normalize_with_depth(self,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
&trait_ref);
|
||||||
|
|
||||||
self.confirm_poly_trait_refs(obligation.cause.clone(),
|
self.confirm_poly_trait_refs(obligation.cause.clone(),
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
obligation.predicate.to_poly_trait_ref(),
|
obligation.predicate.to_poly_trait_ref(),
|
||||||
trait_ref)?;
|
trait_ref)?;
|
||||||
Ok(VtableFnPointerData { fn_ty: self_ty, nested: vec![] })
|
Ok(VtableFnPointerData { fn_ty: self_ty, nested: obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_closure_candidate(&mut self,
|
fn confirm_closure_candidate(&mut self,
|
||||||
|
@ -1378,9 +1378,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_fn_def(self, def_id: DefId,
|
pub fn mk_fn_def(self, def_id: DefId,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
|
||||||
fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
self.mk_ty(TyFnDef(def_id, substs))
|
||||||
self.mk_ty(TyFnDef(def_id, substs, fty))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||||
|
@ -68,6 +68,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
// view of possibly unifying
|
// view of possibly unifying
|
||||||
simplify_type(tcx, mt.ty, can_simplify_params)
|
simplify_type(tcx, mt.ty, can_simplify_params)
|
||||||
}
|
}
|
||||||
|
ty::TyFnDef(def_id, _) |
|
||||||
ty::TyClosure(def_id, _) => {
|
ty::TyClosure(def_id, _) => {
|
||||||
Some(ClosureSimplifiedType(def_id))
|
Some(ClosureSimplifiedType(def_id))
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
ty::TyTuple(ref tys, _) => {
|
ty::TyTuple(ref tys, _) => {
|
||||||
Some(TupleSimplifiedType(tys.len()))
|
Some(TupleSimplifiedType(tys.len()))
|
||||||
}
|
}
|
||||||
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {
|
ty::TyFnPtr(ref f) => {
|
||||||
Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
|
Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
|
||||||
}
|
}
|
||||||
ty::TyProjection(_) | ty::TyParam(_) => {
|
ty::TyProjection(_) | ty::TyParam(_) => {
|
||||||
|
@ -155,9 +155,8 @@ impl FlagComputation {
|
|||||||
self.add_tys(&ts[..]);
|
self.add_tys(&ts[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
&ty::TyFnDef(_, substs, f) => {
|
&ty::TyFnDef(_, substs) => {
|
||||||
self.add_substs(substs);
|
self.add_substs(substs);
|
||||||
self.add_fn_sig(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&ty::TyFnPtr(f) => {
|
&ty::TyFnPtr(f) => {
|
||||||
|
@ -348,7 +348,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
|
|||||||
.filter_map(|ty| characteristic_def_id_of_type(ty))
|
.filter_map(|ty| characteristic_def_id_of_type(ty))
|
||||||
.next(),
|
.next(),
|
||||||
|
|
||||||
ty::TyFnDef(def_id, ..) |
|
ty::TyFnDef(def_id, _) |
|
||||||
ty::TyClosure(def_id, _) => Some(def_id),
|
ty::TyClosure(def_id, _) => Some(def_id),
|
||||||
|
|
||||||
ty::TyBool |
|
ty::TyBool |
|
||||||
|
@ -206,7 +206,7 @@ impl AssociatedItem {
|
|||||||
// late-bound regions, and we don't want method signatures to show up
|
// late-bound regions, and we don't want method signatures to show up
|
||||||
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
|
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
|
||||||
// regions just fine, showing `fn(&MyType)`.
|
// regions just fine, showing `fn(&MyType)`.
|
||||||
format!("{}", tcx.type_of(self.def_id).fn_sig().skip_binder())
|
format!("{}", tcx.fn_sig(self.def_id).skip_binder())
|
||||||
}
|
}
|
||||||
ty::AssociatedKind::Type => format!("type {};", self.name.to_string()),
|
ty::AssociatedKind::Type => format!("type {};", self.name.to_string()),
|
||||||
ty::AssociatedKind::Const => {
|
ty::AssociatedKind::Const => {
|
||||||
|
@ -440,13 +440,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::TyFnDef(a_def_id, a_substs, a_fty),
|
(&ty::TyFnDef(a_def_id, a_substs), &ty::TyFnDef(b_def_id, b_substs))
|
||||||
&ty::TyFnDef(b_def_id, b_substs, b_fty))
|
|
||||||
if a_def_id == b_def_id =>
|
if a_def_id == b_def_id =>
|
||||||
{
|
{
|
||||||
let substs = relate_substs(relation, None, a_substs, b_substs)?;
|
let substs = relate_substs(relation, None, a_substs, b_substs)?;
|
||||||
let fty = relation.relate(&a_fty, &b_fty)?;
|
Ok(tcx.mk_fn_def(a_def_id, substs))
|
||||||
Ok(tcx.mk_fn_def(a_def_id, substs, fty))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::TyFnPtr(a_fty), &ty::TyFnPtr(b_fty)) =>
|
(&ty::TyFnPtr(a_fty), &ty::TyFnPtr(b_fty)) =>
|
||||||
|
@ -531,10 +531,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||||||
ty::TyDynamic(ref trait_ty, ref region) =>
|
ty::TyDynamic(ref trait_ty, ref region) =>
|
||||||
ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
|
ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
|
||||||
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
|
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
|
||||||
ty::TyFnDef(def_id, substs, f) => {
|
ty::TyFnDef(def_id, substs) => {
|
||||||
ty::TyFnDef(def_id,
|
ty::TyFnDef(def_id, substs.fold_with(folder))
|
||||||
substs.fold_with(folder),
|
|
||||||
f.fold_with(folder))
|
|
||||||
}
|
}
|
||||||
ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
|
ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
|
||||||
ty::TyRef(ref r, tm) => {
|
ty::TyRef(ref r, tm) => {
|
||||||
@ -568,9 +566,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||||||
ty::TyDynamic(ref trait_ty, ref reg) =>
|
ty::TyDynamic(ref trait_ty, ref reg) =>
|
||||||
trait_ty.visit_with(visitor) || reg.visit_with(visitor),
|
trait_ty.visit_with(visitor) || reg.visit_with(visitor),
|
||||||
ty::TyTuple(ts, _) => ts.visit_with(visitor),
|
ty::TyTuple(ts, _) => ts.visit_with(visitor),
|
||||||
ty::TyFnDef(_, substs, ref f) => {
|
ty::TyFnDef(_, substs) => substs.visit_with(visitor),
|
||||||
substs.visit_with(visitor) || f.visit_with(visitor)
|
|
||||||
}
|
|
||||||
ty::TyFnPtr(ref f) => f.visit_with(visitor),
|
ty::TyFnPtr(ref f) => f.visit_with(visitor),
|
||||||
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
|
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
|
||||||
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
|
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
|
||||||
|
@ -14,7 +14,7 @@ use hir::def_id::DefId;
|
|||||||
use hir::map::DefPathHash;
|
use hir::map::DefPathHash;
|
||||||
|
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use ty::subst::Substs;
|
use ty::subst::{Substs, Subst};
|
||||||
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
||||||
use ty::{Slice, TyS};
|
use ty::{Slice, TyS};
|
||||||
use ty::subst::Kind;
|
use ty::subst::Kind;
|
||||||
@ -138,7 +138,7 @@ pub enum TypeVariants<'tcx> {
|
|||||||
|
|
||||||
/// The anonymous type of a function declaration/definition. Each
|
/// The anonymous type of a function declaration/definition. Each
|
||||||
/// function has a unique type.
|
/// function has a unique type.
|
||||||
TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>),
|
TyFnDef(DefId, &'tcx Substs<'tcx>),
|
||||||
|
|
||||||
/// A pointer to a function. Written as `fn() -> i32`.
|
/// A pointer to a function. Written as `fn() -> i32`.
|
||||||
TyFnPtr(PolyFnSig<'tcx>),
|
TyFnPtr(PolyFnSig<'tcx>),
|
||||||
@ -1329,9 +1329,12 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
|
pub fn fn_sig(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PolyFnSig<'tcx> {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
TyFnDef(.., f) | TyFnPtr(f) => f,
|
TyFnDef(def_id, substs) => {
|
||||||
|
tcx.fn_sig(def_id).subst(tcx, substs)
|
||||||
|
}
|
||||||
|
TyFnPtr(f) => f,
|
||||||
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
|
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,7 +679,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
|
|||||||
TyRef(_, m) => self.hash(m.mutbl),
|
TyRef(_, m) => self.hash(m.mutbl),
|
||||||
TyClosure(def_id, _) |
|
TyClosure(def_id, _) |
|
||||||
TyAnon(def_id, _) |
|
TyAnon(def_id, _) |
|
||||||
TyFnDef(def_id, ..) => self.def_id(def_id),
|
TyFnDef(def_id, _) => self.def_id(def_id),
|
||||||
TyAdt(d, _) => self.def_id(d.did),
|
TyAdt(d, _) => self.def_id(d.did),
|
||||||
TyFnPtr(f) => {
|
TyFnPtr(f) => {
|
||||||
self.hash(f.unsafety());
|
self.hash(f.unsafety());
|
||||||
|
@ -115,9 +115,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
|||||||
ty::TyTuple(ts, _) => {
|
ty::TyTuple(ts, _) => {
|
||||||
stack.extend(ts.iter().cloned().rev());
|
stack.extend(ts.iter().cloned().rev());
|
||||||
}
|
}
|
||||||
ty::TyFnDef(_, substs, ft) => {
|
ty::TyFnDef(_, substs) => {
|
||||||
stack.extend(substs.types().rev());
|
stack.extend(substs.types().rev());
|
||||||
push_sig_subtypes(stack, ft);
|
|
||||||
}
|
}
|
||||||
ty::TyFnPtr(ft) => {
|
ty::TyFnPtr(ft) => {
|
||||||
push_sig_subtypes(stack, ft);
|
push_sig_subtypes(stack, ft);
|
||||||
|
@ -753,8 +753,14 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
|||||||
}
|
}
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
TyFnDef(def_id, substs, ref bare_fn) => {
|
TyFnDef(def_id, substs) => {
|
||||||
write!(f, "{} {{", bare_fn.0)?;
|
ty::tls::with(|tcx| {
|
||||||
|
let mut sig = tcx.fn_sig(def_id);
|
||||||
|
if let Some(substs) = tcx.lift(&substs) {
|
||||||
|
sig = sig.subst(tcx, substs);
|
||||||
|
}
|
||||||
|
write!(f, "{} {{", sig.0)
|
||||||
|
})?;
|
||||||
parameterized(f, substs, def_id, &[])?;
|
parameterized(f, substs, def_id, &[])?;
|
||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
}
|
}
|
||||||
|
@ -161,18 +161,13 @@ fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
terminator: &'a Option<mir::Terminator<'tcx>>)
|
terminator: &'a Option<mir::Terminator<'tcx>>)
|
||||||
-> Option<(&'a [mir::Operand<'tcx>], Span)> {
|
-> Option<(&'a [mir::Operand<'tcx>], Span)> {
|
||||||
if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
|
if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
|
||||||
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
|
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind {
|
||||||
{
|
if let mir::Operand::Constant(ref func) = *oper {
|
||||||
if let mir::Operand::Constant(ref func) = *oper
|
if let ty::TyFnDef(def_id, _) = func.ty.sty {
|
||||||
{
|
let abi = tcx.fn_sig(def_id).abi();
|
||||||
if let ty::TyFnDef(def_id, _, sig) = func.ty.sty
|
|
||||||
{
|
|
||||||
let abi = sig.abi();
|
|
||||||
let name = tcx.item_name(def_id);
|
let name = tcx.item_name(def_id);
|
||||||
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
|
if abi == Abi::RustIntrinsic && name == "rustc_peek" {
|
||||||
if name == "rustc_peek" {
|
return Some((args, source_info.span));
|
||||||
return Some((args, source_info.span));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use eval;
|
|||||||
|
|
||||||
use rustc::middle::const_val::{ConstEvalErr, ConstVal};
|
use rustc::middle::const_val::{ConstEvalErr, ConstVal};
|
||||||
use rustc::mir::{Field, BorrowKind, Mutability};
|
use rustc::mir::{Field, BorrowKind, Mutability};
|
||||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty, TypeVariants, Region};
|
use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region};
|
||||||
use rustc::ty::subst::{Substs, Kind};
|
use rustc::ty::subst::{Substs, Kind};
|
||||||
use rustc::hir::{self, PatKind, RangeEnd};
|
use rustc::hir::{self, PatKind, RangeEnd};
|
||||||
use rustc::hir::def::{Def, CtorKind};
|
use rustc::hir::def::{Def, CtorKind};
|
||||||
@ -549,8 +549,8 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> {
|
|||||||
let adt_def = self.tcx.adt_def(enum_id);
|
let adt_def = self.tcx.adt_def(enum_id);
|
||||||
if adt_def.variants.len() > 1 {
|
if adt_def.variants.len() > 1 {
|
||||||
let substs = match ty.sty {
|
let substs = match ty.sty {
|
||||||
TypeVariants::TyAdt(_, substs) => substs,
|
ty::TyAdt(_, substs) |
|
||||||
TypeVariants::TyFnDef(_, substs, _) => substs,
|
ty::TyFnDef(_, substs) => substs,
|
||||||
_ => bug!("inappropriate type for def: {:?}", ty.sty),
|
_ => bug!("inappropriate type for def: {:?}", ty.sty),
|
||||||
};
|
};
|
||||||
PatternKind::Variant {
|
PatternKind::Variant {
|
||||||
|
@ -1154,24 +1154,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
|
|||||||
if !def_id_is_transmute(cx, did) {
|
if !def_id_is_transmute(cx, did) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let typ = cx.tables.node_id_to_type(expr.id);
|
let sig = cx.tables.node_id_to_type(expr.id).fn_sig(cx.tcx);
|
||||||
match typ.sty {
|
let from = sig.inputs().skip_binder()[0];
|
||||||
ty::TyFnDef(.., bare_fn) if bare_fn.abi() == RustIntrinsic => {
|
let to = *sig.output().skip_binder();
|
||||||
let from = bare_fn.inputs().skip_binder()[0];
|
return Some((&from.sty, &to.sty));
|
||||||
let to = *bare_fn.output().skip_binder();
|
|
||||||
return Some((&from.sty, &to.sty));
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool {
|
fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool {
|
||||||
match cx.tcx.type_of(def_id).sty {
|
cx.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
|
||||||
ty::TyFnDef(.., bfty) if bfty.abi() == RustIntrinsic => (),
|
|
||||||
_ => return false,
|
|
||||||
}
|
|
||||||
cx.tcx.item_name(def_id) == "transmute"
|
cx.tcx.item_name(def_id) == "transmute"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,7 +659,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
|
fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
|
||||||
let def_id = self.cx.tcx.hir.local_def_id(id);
|
let def_id = self.cx.tcx.hir.local_def_id(id);
|
||||||
let sig = self.cx.tcx.type_of(def_id).fn_sig();
|
let sig = self.cx.tcx.fn_sig(def_id);
|
||||||
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
|
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
|
||||||
|
|
||||||
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
|
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
|
||||||
|
@ -1085,13 +1085,19 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_sig(&self,
|
pub fn fn_sig(&self,
|
||||||
closure_id: DefIndex,
|
id: DefIndex,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||||
-> ty::PolyFnSig<'tcx> {
|
-> ty::PolyFnSig<'tcx> {
|
||||||
match self.entry(closure_id).kind {
|
let sig = match self.entry(id).kind {
|
||||||
EntryKind::Closure(data) => data.decode(self).sig.decode((self, tcx)),
|
EntryKind::Fn(data) |
|
||||||
|
EntryKind::ForeignFn(data) => data.decode(self).sig,
|
||||||
|
EntryKind::Method(data) => data.decode(self).fn_data.sig,
|
||||||
|
EntryKind::Variant(data) |
|
||||||
|
EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(),
|
||||||
|
EntryKind::Closure(data) => data.decode(self).sig,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
}
|
};
|
||||||
|
sig.decode((self, tcx))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -16,6 +16,7 @@ use schema::*;
|
|||||||
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
|
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
|
||||||
EncodedMetadata, EncodedMetadataHashes,
|
EncodedMetadata, EncodedMetadataHashes,
|
||||||
EncodedMetadataHash};
|
EncodedMetadataHash};
|
||||||
|
use rustc::hir::def::CtorKind;
|
||||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
|
||||||
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
|
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
|
||||||
use rustc::ich::Fingerprint;
|
use rustc::ich::Fingerprint;
|
||||||
@ -499,6 +500,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
struct_ctor: None,
|
struct_ctor: None,
|
||||||
|
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
|
||||||
|
Some(self.lazy(&tcx.fn_sig(def_id)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let enum_id = tcx.hir.as_local_node_id(enum_did).unwrap();
|
let enum_id = tcx.hir.as_local_node_id(enum_did).unwrap();
|
||||||
@ -617,6 +623,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
struct_ctor: Some(def_id.index),
|
struct_ctor: Some(def_id.index),
|
||||||
|
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
|
||||||
|
Some(self.lazy(&tcx.fn_sig(def_id)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap();
|
let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap();
|
||||||
@ -695,7 +706,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
};
|
};
|
||||||
FnData {
|
FnData {
|
||||||
constness: hir::Constness::NotConst,
|
constness: hir::Constness::NotConst,
|
||||||
arg_names: arg_names
|
arg_names: arg_names,
|
||||||
|
sig: self.lazy(&tcx.fn_sig(def_id)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bug!()
|
bug!()
|
||||||
@ -747,6 +759,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
|
|
||||||
fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
|
fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
|
||||||
debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id);
|
debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id);
|
||||||
|
let tcx = self.tcx;
|
||||||
|
|
||||||
let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
|
let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
let ast_item = self.tcx.hir.expect_impl_item(node_id);
|
let ast_item = self.tcx.hir.expect_impl_item(node_id);
|
||||||
let impl_item = self.tcx.associated_item(def_id);
|
let impl_item = self.tcx.associated_item(def_id);
|
||||||
@ -768,6 +782,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
FnData {
|
FnData {
|
||||||
constness: sig.constness,
|
constness: sig.constness,
|
||||||
arg_names: self.encode_fn_arg_names_for_body(body),
|
arg_names: self.encode_fn_arg_names_for_body(body),
|
||||||
|
sig: self.lazy(&tcx.fn_sig(def_id)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bug!()
|
bug!()
|
||||||
@ -881,6 +896,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
let data = FnData {
|
let data = FnData {
|
||||||
constness: constness,
|
constness: constness,
|
||||||
arg_names: self.encode_fn_arg_names_for_body(body),
|
arg_names: self.encode_fn_arg_names_for_body(body),
|
||||||
|
sig: self.lazy(&tcx.fn_sig(def_id)),
|
||||||
};
|
};
|
||||||
|
|
||||||
EntryKind::Fn(self.lazy(&data))
|
EntryKind::Fn(self.lazy(&data))
|
||||||
@ -910,6 +926,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
struct_ctor: struct_ctor,
|
struct_ctor: struct_ctor,
|
||||||
|
ctor_sig: None,
|
||||||
}), repr_options)
|
}), repr_options)
|
||||||
}
|
}
|
||||||
hir::ItemUnion(..) => {
|
hir::ItemUnion(..) => {
|
||||||
@ -920,6 +937,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
struct_ctor: None,
|
struct_ctor: None,
|
||||||
|
ctor_sig: None,
|
||||||
}), repr_options)
|
}), repr_options)
|
||||||
}
|
}
|
||||||
hir::ItemDefaultImpl(..) => {
|
hir::ItemDefaultImpl(..) => {
|
||||||
@ -1363,6 +1381,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
|||||||
let data = FnData {
|
let data = FnData {
|
||||||
constness: hir::Constness::NotConst,
|
constness: hir::Constness::NotConst,
|
||||||
arg_names: self.encode_fn_arg_names(names),
|
arg_names: self.encode_fn_arg_names(names),
|
||||||
|
sig: self.lazy(&tcx.fn_sig(def_id)),
|
||||||
};
|
};
|
||||||
EntryKind::ForeignFn(self.lazy(&data))
|
EntryKind::ForeignFn(self.lazy(&data))
|
||||||
}
|
}
|
||||||
|
@ -343,18 +343,18 @@ pub enum EntryKind<'tcx> {
|
|||||||
Type,
|
Type,
|
||||||
Enum(ReprOptions),
|
Enum(ReprOptions),
|
||||||
Field,
|
Field,
|
||||||
Variant(Lazy<VariantData>),
|
Variant(Lazy<VariantData<'tcx>>),
|
||||||
Struct(Lazy<VariantData>, ReprOptions),
|
Struct(Lazy<VariantData<'tcx>>, ReprOptions),
|
||||||
Union(Lazy<VariantData>, ReprOptions),
|
Union(Lazy<VariantData<'tcx>>, ReprOptions),
|
||||||
Fn(Lazy<FnData>),
|
Fn(Lazy<FnData<'tcx>>),
|
||||||
ForeignFn(Lazy<FnData>),
|
ForeignFn(Lazy<FnData<'tcx>>),
|
||||||
Mod(Lazy<ModData>),
|
Mod(Lazy<ModData>),
|
||||||
MacroDef(Lazy<MacroDef>),
|
MacroDef(Lazy<MacroDef>),
|
||||||
Closure(Lazy<ClosureData<'tcx>>),
|
Closure(Lazy<ClosureData<'tcx>>),
|
||||||
Trait(Lazy<TraitData<'tcx>>),
|
Trait(Lazy<TraitData<'tcx>>),
|
||||||
Impl(Lazy<ImplData<'tcx>>),
|
Impl(Lazy<ImplData<'tcx>>),
|
||||||
DefaultImpl(Lazy<ImplData<'tcx>>),
|
DefaultImpl(Lazy<ImplData<'tcx>>),
|
||||||
Method(Lazy<MethodData>),
|
Method(Lazy<MethodData<'tcx>>),
|
||||||
AssociatedType(AssociatedContainer),
|
AssociatedType(AssociatedContainer),
|
||||||
AssociatedConst(AssociatedContainer, u8),
|
AssociatedConst(AssociatedContainer, u8),
|
||||||
}
|
}
|
||||||
@ -439,27 +439,33 @@ pub struct MacroDef {
|
|||||||
impl_stable_hash_for!(struct MacroDef { body, legacy });
|
impl_stable_hash_for!(struct MacroDef { body, legacy });
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct FnData {
|
pub struct FnData<'tcx> {
|
||||||
pub constness: hir::Constness,
|
pub constness: hir::Constness,
|
||||||
pub arg_names: LazySeq<ast::Name>,
|
pub arg_names: LazySeq<ast::Name>,
|
||||||
|
pub sig: Lazy<ty::PolyFnSig<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_stable_hash_for!(struct FnData { constness, arg_names });
|
impl_stable_hash_for!(struct FnData<'tcx> { constness, arg_names, sig });
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct VariantData {
|
pub struct VariantData<'tcx> {
|
||||||
pub ctor_kind: CtorKind,
|
pub ctor_kind: CtorKind,
|
||||||
pub discr: ty::VariantDiscr,
|
pub discr: ty::VariantDiscr,
|
||||||
|
|
||||||
/// If this is a struct's only variant, this
|
/// If this is a struct's only variant, this
|
||||||
/// is the index of the "struct ctor" item.
|
/// is the index of the "struct ctor" item.
|
||||||
pub struct_ctor: Option<DefIndex>,
|
pub struct_ctor: Option<DefIndex>,
|
||||||
|
|
||||||
|
/// If this is a tuple struct or variant
|
||||||
|
/// ctor, this is its "function" signature.
|
||||||
|
pub ctor_sig: Option<Lazy<ty::PolyFnSig<'tcx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_stable_hash_for!(struct VariantData {
|
impl_stable_hash_for!(struct VariantData<'tcx> {
|
||||||
ctor_kind,
|
ctor_kind,
|
||||||
discr,
|
discr,
|
||||||
struct_ctor
|
struct_ctor,
|
||||||
|
ctor_sig
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
@ -543,12 +549,12 @@ impl AssociatedContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct MethodData {
|
pub struct MethodData<'tcx> {
|
||||||
pub fn_data: FnData,
|
pub fn_data: FnData<'tcx>,
|
||||||
pub container: AssociatedContainer,
|
pub container: AssociatedContainer,
|
||||||
pub has_self: bool,
|
pub has_self: bool,
|
||||||
}
|
}
|
||||||
impl_stable_hash_for!(struct MethodData { fn_data, container, has_self });
|
impl_stable_hash_for!(struct MethodData<'tcx> { fn_data, container, has_self });
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
pub struct ClosureData<'tcx> {
|
pub struct ClosureData<'tcx> {
|
||||||
|
@ -205,11 +205,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
||||||
let diverges = expr.ty.is_never();
|
let diverges = expr.ty.is_never();
|
||||||
let intrinsic = match ty.sty {
|
let intrinsic = match ty.sty {
|
||||||
ty::TyFnDef(def_id, _, ref f) if
|
ty::TyFnDef(def_id, _) => {
|
||||||
f.abi() == Abi::RustIntrinsic ||
|
let f = ty.fn_sig(this.hir.tcx());
|
||||||
f.abi() == Abi::PlatformIntrinsic =>
|
if f.abi() == Abi::RustIntrinsic ||
|
||||||
{
|
f.abi() == Abi::PlatformIntrinsic {
|
||||||
Some(this.hir.tcx().item_name(def_id).as_str())
|
Some(this.hir.tcx().item_name(def_id).as_str())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,6 @@ use rustc::middle::const_val::ConstVal;
|
|||||||
use rustc::ty::{self, AdtKind, VariantDef, Ty};
|
use rustc::ty::{self, AdtKind, VariantDef, Ty};
|
||||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
|
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
|
||||||
use rustc::ty::cast::CastKind as TyCastKind;
|
use rustc::ty::cast::CastKind as TyCastKind;
|
||||||
use rustc::ty::subst::Subst;
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
|
||||||
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||||
@ -586,7 +585,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
});
|
});
|
||||||
Expr {
|
Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: cx.tcx.type_of(def_id).subst(cx.tcx, substs),
|
ty: cx.tcx().mk_fn_def(def_id, substs),
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Literal {
|
kind: ExprKind::Literal {
|
||||||
literal: Literal::Value {
|
literal: Literal::Value {
|
||||||
|
@ -58,7 +58,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
// types in the MIR. They will be substituted again with
|
// types in the MIR. They will be substituted again with
|
||||||
// the param-substs, but because they are concrete, this
|
// the param-substs, but because they are concrete, this
|
||||||
// will not do any harm.
|
// will not do any harm.
|
||||||
let sig = tcx.erase_late_bound_regions(&ty.fn_sig());
|
let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
|
||||||
let arg_tys = sig.inputs();
|
let arg_tys = sig.inputs();
|
||||||
|
|
||||||
build_call_shim(
|
build_call_shim(
|
||||||
@ -153,8 +153,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
} else {
|
} else {
|
||||||
Substs::identity_for_item(tcx, def_id)
|
Substs::identity_for_item(tcx, def_id)
|
||||||
};
|
};
|
||||||
let fn_ty = tcx.type_of(def_id).subst(tcx, substs);
|
let sig = tcx.fn_sig(def_id).subst(tcx, substs);
|
||||||
let sig = tcx.erase_late_bound_regions(&fn_ty.fn_sig());
|
let sig = tcx.erase_late_bound_regions(&sig);
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
|
|
||||||
let source_info = SourceInfo { span, scope: ARGUMENT_VISIBILITY_SCOPE };
|
let source_info = SourceInfo { span, scope: ARGUMENT_VISIBILITY_SCOPE };
|
||||||
@ -276,8 +276,8 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
call_kind={:?}, untuple_args={:?})",
|
call_kind={:?}, untuple_args={:?})",
|
||||||
def_id, rcvr_adjustment, call_kind, untuple_args);
|
def_id, rcvr_adjustment, call_kind, untuple_args);
|
||||||
|
|
||||||
let fn_ty = tcx.type_of(def_id);
|
let sig = tcx.fn_sig(def_id);
|
||||||
let sig = tcx.erase_late_bound_regions(&fn_ty.fn_sig());
|
let sig = tcx.erase_late_bound_regions(&sig);
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
|
|
||||||
debug!("build_call_shim: sig={:?}", sig);
|
debug!("build_call_shim: sig={:?}", sig);
|
||||||
@ -409,11 +409,8 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
|
|||||||
{
|
{
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
let def_id = tcx.hir.local_def_id(ctor_id);
|
let def_id = tcx.hir.local_def_id(ctor_id);
|
||||||
let sig = match tcx.type_of(def_id).sty {
|
let sig = tcx.no_late_bound_regions(&tcx.fn_sig(def_id))
|
||||||
ty::TyFnDef(_, _, fty) => tcx.no_late_bound_regions(&fty)
|
.expect("LBR in ADT constructor signature");
|
||||||
.expect("LBR in ADT constructor signature"),
|
|
||||||
_ => bug!("unexpected type for ctor {:?}", def_id)
|
|
||||||
};
|
|
||||||
let sig = tcx.erase_regions(&sig);
|
let sig = tcx.erase_regions(&sig);
|
||||||
|
|
||||||
let (adt_def, substs) = match sig.output().sty {
|
let (adt_def, substs) = match sig.output().sty {
|
||||||
|
@ -87,7 +87,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||||||
let terminator = bb_data.terminator();
|
let terminator = bb_data.terminator();
|
||||||
if let TerminatorKind::Call {
|
if let TerminatorKind::Call {
|
||||||
func: Operand::Constant(ref f), .. } = terminator.kind {
|
func: Operand::Constant(ref f), .. } = terminator.kind {
|
||||||
if let ty::TyFnDef(callee_def_id, substs, _) = f.ty.sty {
|
if let ty::TyFnDef(callee_def_id, substs) = f.ty.sty {
|
||||||
callsites.push_back(CallSite {
|
callsites.push_back(CallSite {
|
||||||
callee: callee_def_id,
|
callee: callee_def_id,
|
||||||
substs: substs,
|
substs: substs,
|
||||||
@ -131,7 +131,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||||||
let terminator = bb_data.terminator();
|
let terminator = bb_data.terminator();
|
||||||
if let TerminatorKind::Call {
|
if let TerminatorKind::Call {
|
||||||
func: Operand::Constant(ref f), .. } = terminator.kind {
|
func: Operand::Constant(ref f), .. } = terminator.kind {
|
||||||
if let ty::TyFnDef(callee_def_id, substs, _) = f.ty.sty {
|
if let ty::TyFnDef(callee_def_id, substs) = f.ty.sty {
|
||||||
// Don't inline the same function multiple times.
|
// Don't inline the same function multiple times.
|
||||||
if callsite.callee != callee_def_id {
|
if callsite.callee != callee_def_id {
|
||||||
callsites.push_back(CallSite {
|
callsites.push_back(CallSite {
|
||||||
@ -270,8 +270,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::Call {func: Operand::Constant(ref f), .. } => {
|
TerminatorKind::Call {func: Operand::Constant(ref f), .. } => {
|
||||||
if let ty::TyFnDef(.., f) = f.ty.sty {
|
if let ty::TyFnDef(def_id, _) = f.ty.sty {
|
||||||
// Don't give intrinsics the extra penalty for calls
|
// Don't give intrinsics the extra penalty for calls
|
||||||
|
let f = tcx.fn_sig(def_id);
|
||||||
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
|
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
|
||||||
cost += INSTR_COST;
|
cost += INSTR_COST;
|
||||||
} else {
|
} else {
|
||||||
|
@ -750,8 +750,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||||||
|
|
||||||
let fn_ty = func.ty(self.mir, self.tcx);
|
let fn_ty = func.ty(self.mir, self.tcx);
|
||||||
let (is_shuffle, is_const_fn) = match fn_ty.sty {
|
let (is_shuffle, is_const_fn) = match fn_ty.sty {
|
||||||
ty::TyFnDef(def_id, _, f) => {
|
ty::TyFnDef(def_id, _) => {
|
||||||
(f.abi() == Abi::PlatformIntrinsic &&
|
(self.tcx.fn_sig(def_id).abi() == Abi::PlatformIntrinsic &&
|
||||||
self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
|
self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
|
||||||
self.tcx.is_const_fn(def_id))
|
self.tcx.is_const_fn(def_id))
|
||||||
}
|
}
|
||||||
|
@ -462,7 +462,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||||||
let func_ty = func.ty(mir, tcx);
|
let func_ty = func.ty(mir, tcx);
|
||||||
debug!("check_terminator: call, func_ty={:?}", func_ty);
|
debug!("check_terminator: call, func_ty={:?}", func_ty);
|
||||||
let sig = match func_ty.sty {
|
let sig = match func_ty.sty {
|
||||||
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => sig,
|
ty::TyFnDef(..) | ty::TyFnPtr(_) => func_ty.fn_sig(tcx),
|
||||||
_ => {
|
_ => {
|
||||||
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
||||||
return;
|
return;
|
||||||
|
@ -400,7 +400,13 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ty(&mut self) -> &mut Self {
|
fn ty(&mut self) -> &mut Self {
|
||||||
self.ev.tcx.type_of(self.item_def_id).visit_with(self);
|
let ty = self.ev.tcx.type_of(self.item_def_id);
|
||||||
|
ty.visit_with(self);
|
||||||
|
if let ty::TyFnDef(def_id, _) = ty.sty {
|
||||||
|
if def_id == self.item_def_id {
|
||||||
|
self.ev.tcx.fn_sig(def_id).visit_with(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,7 +916,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ty(&mut self) -> &mut Self {
|
fn ty(&mut self) -> &mut Self {
|
||||||
self.tcx.type_of(self.item_def_id).visit_with(self);
|
let ty = self.tcx.type_of(self.item_def_id);
|
||||||
|
ty.visit_with(self);
|
||||||
|
if let ty::TyFnDef(def_id, _) = ty.sty {
|
||||||
|
if def_id == self.item_def_id {
|
||||||
|
self.tcx.fn_sig(def_id).visit_with(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +154,13 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
assert!(!item_type.has_erasable_regions());
|
assert!(!item_type.has_erasable_regions());
|
||||||
hasher.visit_ty(item_type);
|
hasher.visit_ty(item_type);
|
||||||
|
|
||||||
|
// If this is a function, we hash the signature as well.
|
||||||
|
// This is not *strictly* needed, but it may help in some
|
||||||
|
// situations, see the `run-make/a-b-a-linker-guard` test.
|
||||||
|
if let ty::TyFnDef(..) = item_type.sty {
|
||||||
|
item_type.fn_sig(tcx).visit_with(&mut hasher);
|
||||||
|
}
|
||||||
|
|
||||||
// also include any type parameters (for generic items)
|
// also include any type parameters (for generic items)
|
||||||
if let Some(substs) = substs {
|
if let Some(substs) = substs {
|
||||||
assert!(!substs.has_erasable_regions());
|
assert!(!substs.has_erasable_regions());
|
||||||
|
@ -587,7 +587,7 @@ fn visit_fn_use<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
|||||||
is_direct_call: bool,
|
is_direct_call: bool,
|
||||||
output: &mut Vec<TransItem<'tcx>>)
|
output: &mut Vec<TransItem<'tcx>>)
|
||||||
{
|
{
|
||||||
if let ty::TyFnDef(def_id, substs, _) = ty.sty {
|
if let ty::TyFnDef(def_id, substs) = ty.sty {
|
||||||
let instance = monomorphize::resolve(scx, def_id, substs);
|
let instance = monomorphize::resolve(scx, def_id, substs);
|
||||||
visit_instance_use(scx, instance, is_direct_call, output);
|
visit_instance_use(scx, instance, is_direct_call, output);
|
||||||
}
|
}
|
||||||
|
@ -495,9 +495,9 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
-> ty::PolyFnSig<'tcx>
|
-> ty::PolyFnSig<'tcx>
|
||||||
{
|
{
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyFnDef(_, _, sig) => sig,
|
ty::TyFnDef(..) |
|
||||||
// Shims currently have type TyFnPtr. Not sure this should remain.
|
// Shims currently have type TyFnPtr. Not sure this should remain.
|
||||||
ty::TyFnPtr(sig) => sig,
|
ty::TyFnPtr(_) => ty.fn_sig(ccx.tcx()),
|
||||||
ty::TyClosure(def_id, substs) => {
|
ty::TyClosure(def_id, substs) => {
|
||||||
let tcx = ccx.tcx();
|
let tcx = ccx.tcx();
|
||||||
let sig = tcx.fn_sig(def_id).subst(tcx, substs.substs);
|
let sig = tcx.fn_sig(def_id).subst(tcx, substs.substs);
|
||||||
|
@ -488,7 +488,6 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
debug!("type_metadata: {:?}", t);
|
debug!("type_metadata: {:?}", t);
|
||||||
|
|
||||||
let sty = &t.sty;
|
|
||||||
let ptr_metadata = |ty: Ty<'tcx>| {
|
let ptr_metadata = |ty: Ty<'tcx>| {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TySlice(typ) => {
|
ty::TySlice(typ) => {
|
||||||
@ -518,7 +517,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
|
let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.sty {
|
||||||
ty::TyNever |
|
ty::TyNever |
|
||||||
ty::TyBool |
|
ty::TyBool |
|
||||||
ty::TyChar |
|
ty::TyChar |
|
||||||
@ -557,10 +556,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
Err(metadata) => return metadata,
|
Err(metadata) => return metadata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::TyFnDef(.., sig) | ty::TyFnPtr(sig) => {
|
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||||
let fn_metadata = subroutine_type_metadata(cx,
|
let fn_metadata = subroutine_type_metadata(cx,
|
||||||
unique_type_id,
|
unique_type_id,
|
||||||
sig,
|
t.fn_sig(cx.tcx()),
|
||||||
usage_site_span).metadata;
|
usage_site_span).metadata;
|
||||||
match debug_context(cx).type_map
|
match debug_context(cx).type_map
|
||||||
.borrow()
|
.borrow()
|
||||||
@ -610,7 +609,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
usage_site_span).finalize(cx)
|
usage_site_span).finalize(cx)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bug!("debuginfo: unexpected type in type_metadata: {:?}", sty)
|
bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
push_type_params(cx, principal.substs, output);
|
push_type_params(cx, principal.substs, output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::TyFnDef(.., sig) |
|
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||||
ty::TyFnPtr(sig) => {
|
let sig = t.fn_sig(cx.tcx());
|
||||||
if sig.unsafety() == hir::Unsafety::Unsafe {
|
if sig.unsafety() == hir::Unsafety::Unsafe {
|
||||||
output.push_str("unsafe ");
|
output.push_str("unsafe ");
|
||||||
}
|
}
|
||||||
|
@ -95,11 +95,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
|||||||
let ccx = bcx.ccx;
|
let ccx = bcx.ccx;
|
||||||
let tcx = ccx.tcx();
|
let tcx = ccx.tcx();
|
||||||
|
|
||||||
let (def_id, substs, sig) = match callee_ty.sty {
|
let (def_id, substs) = match callee_ty.sty {
|
||||||
ty::TyFnDef(def_id, substs, sig) => (def_id, substs, sig),
|
ty::TyFnDef(def_id, substs) => (def_id, substs),
|
||||||
_ => bug!("expected fn item type, found {}", callee_ty)
|
_ => bug!("expected fn item type, found {}", callee_ty)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let sig = callee_ty.fn_sig(tcx);
|
||||||
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
|
||||||
let arg_tys = sig.inputs();
|
let arg_tys = sig.inputs();
|
||||||
let ret_ty = sig.output();
|
let ret_ty = sig.output();
|
||||||
@ -986,7 +987,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
|
|
||||||
|
|
||||||
let tcx = bcx.tcx();
|
let tcx = bcx.tcx();
|
||||||
let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig());
|
let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig(tcx));
|
||||||
let arg_tys = sig.inputs();
|
let arg_tys = sig.inputs();
|
||||||
|
|
||||||
// every intrinsic takes a SIMD vector as its first argument
|
// every intrinsic takes a SIMD vector as its first argument
|
||||||
|
@ -404,20 +404,18 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||||||
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
|
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
|
||||||
let callee = self.trans_operand(&bcx, func);
|
let callee = self.trans_operand(&bcx, func);
|
||||||
|
|
||||||
let (instance, mut llfn, sig) = match callee.ty.sty {
|
let (instance, mut llfn) = match callee.ty.sty {
|
||||||
ty::TyFnDef(def_id, substs, sig) => {
|
ty::TyFnDef(def_id, substs) => {
|
||||||
(Some(monomorphize::resolve(bcx.ccx.shared(), def_id, substs)),
|
(Some(monomorphize::resolve(bcx.ccx.shared(), def_id, substs)),
|
||||||
None,
|
None)
|
||||||
sig)
|
|
||||||
}
|
}
|
||||||
ty::TyFnPtr(sig) => {
|
ty::TyFnPtr(_) => {
|
||||||
(None,
|
(None, Some(callee.immediate()))
|
||||||
Some(callee.immediate()),
|
|
||||||
sig)
|
|
||||||
}
|
}
|
||||||
_ => bug!("{} is not callable", callee.ty)
|
_ => bug!("{} is not callable", callee.ty)
|
||||||
};
|
};
|
||||||
let def = instance.map(|i| i.def);
|
let def = instance.map(|i| i.def);
|
||||||
|
let sig = callee.ty.fn_sig(bcx.tcx());
|
||||||
let sig = bcx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
let sig = bcx.tcx().erase_late_bound_regions_and_normalize(&sig);
|
||||||
let abi = sig.abi;
|
let abi = sig.abi;
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||||||
let fn_ty = func.ty(self.mir, tcx);
|
let fn_ty = func.ty(self.mir, tcx);
|
||||||
let fn_ty = self.monomorphize(&fn_ty);
|
let fn_ty = self.monomorphize(&fn_ty);
|
||||||
let (def_id, substs) = match fn_ty.sty {
|
let (def_id, substs) = match fn_ty.sty {
|
||||||
ty::TyFnDef(def_id, substs, _) => (def_id, substs),
|
ty::TyFnDef(def_id, substs) => (def_id, substs),
|
||||||
_ => span_bug!(span, "calling {:?} (of type {}) in constant",
|
_ => span_bug!(span, "calling {:?} (of type {}) in constant",
|
||||||
func, fn_ty)
|
func, fn_ty)
|
||||||
};
|
};
|
||||||
@ -560,7 +560,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||||||
let val = match *kind {
|
let val = match *kind {
|
||||||
mir::CastKind::ReifyFnPointer => {
|
mir::CastKind::ReifyFnPointer => {
|
||||||
match operand.ty.sty {
|
match operand.ty.sty {
|
||||||
ty::TyFnDef(def_id, substs, _) => {
|
ty::TyFnDef(def_id, substs) => {
|
||||||
callee::resolve_and_get_fn(self.ccx, def_id, substs)
|
callee::resolve_and_get_fn(self.ccx, def_id, substs)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -180,7 +180,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||||||
let val = match *kind {
|
let val = match *kind {
|
||||||
mir::CastKind::ReifyFnPointer => {
|
mir::CastKind::ReifyFnPointer => {
|
||||||
match operand.ty.sty {
|
match operand.ty.sty {
|
||||||
ty::TyFnDef(def_id, substs, _) => {
|
ty::TyFnDef(def_id, substs) => {
|
||||||
OperandValue::Immediate(
|
OperandValue::Immediate(
|
||||||
callee::resolve_and_get_fn(bcx.ccx, def_id, substs))
|
callee::resolve_and_get_fn(bcx.ccx, def_id, substs))
|
||||||
}
|
}
|
||||||
|
@ -165,9 +165,11 @@ pub fn resolve<'a, 'tcx>(
|
|||||||
} else {
|
} else {
|
||||||
let item_type = def_ty(scx, def_id, substs);
|
let item_type = def_ty(scx, def_id, substs);
|
||||||
let def = match item_type.sty {
|
let def = match item_type.sty {
|
||||||
ty::TyFnDef(_, _, f) if
|
ty::TyFnDef(..) if {
|
||||||
f.abi() == Abi::RustIntrinsic ||
|
let f = item_type.fn_sig(scx.tcx());
|
||||||
f.abi() == Abi::PlatformIntrinsic =>
|
f.abi() == Abi::RustIntrinsic ||
|
||||||
|
f.abi() == Abi::PlatformIntrinsic
|
||||||
|
} =>
|
||||||
{
|
{
|
||||||
debug!(" => intrinsic");
|
debug!(" => intrinsic");
|
||||||
ty::InstanceDef::Intrinsic(def_id)
|
ty::InstanceDef::Intrinsic(def_id)
|
||||||
|
@ -401,8 +401,9 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
|||||||
output);
|
output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::TyFnDef(.., sig) |
|
ty::TyFnDef(..) |
|
||||||
ty::TyFnPtr(sig) => {
|
ty::TyFnPtr(_) => {
|
||||||
|
let sig = t.fn_sig(self.tcx);
|
||||||
if sig.unsafety() == hir::Unsafety::Unsafe {
|
if sig.unsafety() == hir::Unsafety::Unsafe {
|
||||||
output.push_str("unsafe ");
|
output.push_str("unsafe ");
|
||||||
}
|
}
|
||||||
|
@ -619,7 +619,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// Type check the path.
|
// Type check the path.
|
||||||
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
|
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
|
||||||
// Replace constructor type with constructed type for tuple struct patterns.
|
// Replace constructor type with constructed type for tuple struct patterns.
|
||||||
let pat_ty = pat_ty.fn_sig().output();
|
let pat_ty = pat_ty.fn_sig(tcx).output();
|
||||||
let pat_ty = tcx.no_late_bound_regions(&pat_ty).expect("expected fn type");
|
let pat_ty = tcx.no_late_bound_regions(&pat_ty).expect("expected fn type");
|
||||||
self.demand_eqtype(pat.span, expected, pat_ty);
|
self.demand_eqtype(pat.span, expected, pat_ty);
|
||||||
|
|
||||||
|
@ -196,8 +196,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
expected: Expectation<'tcx>)
|
expected: Expectation<'tcx>)
|
||||||
-> Ty<'tcx> {
|
-> Ty<'tcx> {
|
||||||
let (fn_sig, def_span) = match callee_ty.sty {
|
let (fn_sig, def_span) = match callee_ty.sty {
|
||||||
ty::TyFnDef(def_id, .., sig) => {
|
ty::TyFnDef(def_id, _) => {
|
||||||
(sig, self.tcx.hir.span_if_local(def_id))
|
(callee_ty.fn_sig(self.tcx), self.tcx.hir.span_if_local(def_id))
|
||||||
}
|
}
|
||||||
ty::TyFnPtr(sig) => (sig, None),
|
ty::TyFnPtr(sig) => (sig, None),
|
||||||
ref t => {
|
ref t => {
|
||||||
|
@ -356,8 +356,9 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||||||
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
|
(Some(t_from), Some(t_cast)) => (t_from, t_cast),
|
||||||
// Function item types may need to be reified before casts.
|
// Function item types may need to be reified before casts.
|
||||||
(None, Some(t_cast)) => {
|
(None, Some(t_cast)) => {
|
||||||
if let ty::TyFnDef(.., f) = self.expr_ty.sty {
|
if let ty::TyFnDef(..) = self.expr_ty.sty {
|
||||||
// Attempt a coercion to a fn pointer type.
|
// Attempt a coercion to a fn pointer type.
|
||||||
|
let f = self.expr_ty.fn_sig(fcx.tcx);
|
||||||
let res = fcx.try_coerce(self.expr,
|
let res = fcx.try_coerce(self.expr,
|
||||||
self.expr_ty,
|
self.expr_ty,
|
||||||
self.expr_diverges,
|
self.expr_diverges,
|
||||||
|
@ -210,13 +210,13 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match a.sty {
|
match a.sty {
|
||||||
ty::TyFnDef(.., a_f) => {
|
ty::TyFnDef(..) => {
|
||||||
// Function items are coercible to any closure
|
// Function items are coercible to any closure
|
||||||
// type; function pointers are not (that would
|
// type; function pointers are not (that would
|
||||||
// require double indirection).
|
// require double indirection).
|
||||||
// Additionally, we permit coercion of function
|
// Additionally, we permit coercion of function
|
||||||
// items to drop the unsafe qualifier.
|
// items to drop the unsafe qualifier.
|
||||||
self.coerce_from_fn_item(a, a_f, b)
|
self.coerce_from_fn_item(a, b)
|
||||||
}
|
}
|
||||||
ty::TyFnPtr(a_f) => {
|
ty::TyFnPtr(a_f) => {
|
||||||
// We permit coercion of fn pointers to drop the
|
// We permit coercion of fn pointers to drop the
|
||||||
@ -600,7 +600,6 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn coerce_from_fn_item(&self,
|
fn coerce_from_fn_item(&self,
|
||||||
a: Ty<'tcx>,
|
a: Ty<'tcx>,
|
||||||
fn_ty_a: ty::PolyFnSig<'tcx>,
|
|
||||||
b: Ty<'tcx>)
|
b: Ty<'tcx>)
|
||||||
-> CoerceResult<'tcx> {
|
-> CoerceResult<'tcx> {
|
||||||
//! Attempts to coerce from the type of a Rust function item
|
//! Attempts to coerce from the type of a Rust function item
|
||||||
@ -612,9 +611,17 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
match b.sty {
|
match b.sty {
|
||||||
ty::TyFnPtr(_) => {
|
ty::TyFnPtr(_) => {
|
||||||
let a_fn_pointer = self.tcx.mk_fn_ptr(fn_ty_a);
|
let a_sig = a.fn_sig(self.tcx);
|
||||||
self.coerce_from_safe_fn(a_fn_pointer, fn_ty_a, b,
|
let InferOk { value: a_sig, mut obligations } =
|
||||||
simple(Adjust::ReifyFnPointer), simple(Adjust::ReifyFnPointer))
|
self.normalize_associated_types_in_as_infer_ok(self.cause.span, &a_sig);
|
||||||
|
|
||||||
|
let a_fn_pointer = self.tcx.mk_fn_ptr(a_sig);
|
||||||
|
let InferOk { value, obligations: o2 } =
|
||||||
|
self.coerce_from_safe_fn(a_fn_pointer, a_sig, b,
|
||||||
|
simple(Adjust::ReifyFnPointer), simple(Adjust::ReifyFnPointer))?;
|
||||||
|
|
||||||
|
obligations.extend(o2);
|
||||||
|
Ok(InferOk { value, obligations })
|
||||||
}
|
}
|
||||||
_ => self.unify_and(a, b, identity),
|
_ => self.unify_and(a, b, identity),
|
||||||
}
|
}
|
||||||
@ -775,42 +782,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// Special-case that coercion alone cannot handle:
|
// Special-case that coercion alone cannot handle:
|
||||||
// Two function item types of differing IDs or Substs.
|
// Two function item types of differing IDs or Substs.
|
||||||
match (&prev_ty.sty, &new_ty.sty) {
|
if let (&ty::TyFnDef(..), &ty::TyFnDef(..)) = (&prev_ty.sty, &new_ty.sty) {
|
||||||
(&ty::TyFnDef(a_def_id, a_substs, a_fty), &ty::TyFnDef(b_def_id, b_substs, b_fty)) => {
|
// Don't reify if the function types have a LUB, i.e. they
|
||||||
// The signature must always match.
|
// are the same function and their parameters have a LUB.
|
||||||
let fty = self.at(cause, self.param_env)
|
let lub_ty = self.commit_if_ok(|_| {
|
||||||
.trace(prev_ty, new_ty)
|
self.at(cause, self.param_env)
|
||||||
.lub(&a_fty, &b_fty)
|
.lub(prev_ty, new_ty)
|
||||||
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||||
|
});
|
||||||
|
|
||||||
if a_def_id == b_def_id {
|
if lub_ty.is_ok() {
|
||||||
// Same function, maybe the parameters match.
|
// We have a LUB of prev_ty and new_ty, just return it.
|
||||||
let substs = self.commit_if_ok(|_| {
|
return lub_ty;
|
||||||
self.at(cause, self.param_env)
|
|
||||||
.trace(prev_ty, new_ty)
|
|
||||||
.lub(&a_substs, &b_substs)
|
|
||||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Ok(substs) = substs {
|
|
||||||
// We have a LUB of prev_ty and new_ty, just return it.
|
|
||||||
return Ok(self.tcx.mk_fn_def(a_def_id, substs, fty));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reify both sides and return the reified fn pointer type.
|
|
||||||
let fn_ptr = self.tcx.mk_fn_ptr(fty);
|
|
||||||
for expr in exprs.iter().map(|e| e.as_coercion_site()).chain(Some(new)) {
|
|
||||||
// The only adjustment that can produce an fn item is
|
|
||||||
// `NeverToAny`, so this should always be valid.
|
|
||||||
self.apply_adjustments(expr, vec![Adjustment {
|
|
||||||
kind: Adjust::ReifyFnPointer,
|
|
||||||
target: fn_ptr
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
return Ok(fn_ptr);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
|
// The signature must match.
|
||||||
|
let a_sig = prev_ty.fn_sig(self.tcx);
|
||||||
|
let a_sig = self.normalize_associated_types_in(new.span, &a_sig);
|
||||||
|
let b_sig = new_ty.fn_sig(self.tcx);
|
||||||
|
let b_sig = self.normalize_associated_types_in(new.span, &b_sig);
|
||||||
|
let sig = self.at(cause, self.param_env)
|
||||||
|
.trace(prev_ty, new_ty)
|
||||||
|
.lub(&a_sig, &b_sig)
|
||||||
|
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
||||||
|
|
||||||
|
// Reify both sides and return the reified fn pointer type.
|
||||||
|
let fn_ptr = self.tcx.mk_fn_ptr(sig);
|
||||||
|
for expr in exprs.iter().map(|e| e.as_coercion_site()).chain(Some(new)) {
|
||||||
|
// The only adjustment that can produce an fn item is
|
||||||
|
// `NeverToAny`, so this should always be valid.
|
||||||
|
self.apply_adjustments(expr, vec![Adjustment {
|
||||||
|
kind: Adjust::ReifyFnPointer,
|
||||||
|
target: fn_ptr
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return Ok(fn_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut coerce = Coerce::new(self, cause.clone());
|
let mut coerce = Coerce::new(self, cause.clone());
|
||||||
|
@ -256,17 +256,10 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
// Compute skolemized form of impl and trait method tys.
|
// Compute skolemized form of impl and trait method tys.
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
|
|
||||||
let m_sig = |method: &ty::AssociatedItem| {
|
|
||||||
match tcx.type_of(method.def_id).sty {
|
|
||||||
ty::TyFnDef(_, _, f) => f,
|
|
||||||
_ => bug!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (impl_sig, _) =
|
let (impl_sig, _) =
|
||||||
infcx.replace_late_bound_regions_with_fresh_var(impl_m_span,
|
infcx.replace_late_bound_regions_with_fresh_var(impl_m_span,
|
||||||
infer::HigherRankedType,
|
infer::HigherRankedType,
|
||||||
&m_sig(impl_m));
|
&tcx.fn_sig(impl_m.def_id));
|
||||||
let impl_sig =
|
let impl_sig =
|
||||||
inh.normalize_associated_types_in(impl_m_span,
|
inh.normalize_associated_types_in(impl_m_span,
|
||||||
impl_m_node_id,
|
impl_m_node_id,
|
||||||
@ -277,7 +270,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
let trait_sig = inh.liberate_late_bound_regions(
|
let trait_sig = inh.liberate_late_bound_regions(
|
||||||
impl_m.def_id,
|
impl_m.def_id,
|
||||||
&m_sig(trait_m));
|
&tcx.fn_sig(trait_m.def_id));
|
||||||
let trait_sig =
|
let trait_sig =
|
||||||
trait_sig.subst(tcx, trait_to_skol_substs);
|
trait_sig.subst(tcx, trait_to_skol_substs);
|
||||||
let trait_sig =
|
let trait_sig =
|
||||||
@ -507,8 +500,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
ty::ImplContainer(_) => impl_trait_ref.self_ty(),
|
ty::ImplContainer(_) => impl_trait_ref.self_ty(),
|
||||||
ty::TraitContainer(_) => tcx.mk_self_type()
|
ty::TraitContainer(_) => tcx.mk_self_type()
|
||||||
};
|
};
|
||||||
let method_ty = tcx.type_of(method.def_id);
|
let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
|
||||||
let self_arg_ty = *method_ty.fn_sig().input(0).skip_binder();
|
|
||||||
match ExplicitSelf::determine(untransformed_self_ty, self_arg_ty) {
|
match ExplicitSelf::determine(untransformed_self_ty, self_arg_ty) {
|
||||||
ExplicitSelf::ByValue => "self".to_string(),
|
ExplicitSelf::ByValue => "self".to_string(),
|
||||||
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
|
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
|
||||||
@ -637,14 +629,8 @@ fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
trait_m: &ty::AssociatedItem,
|
trait_m: &ty::AssociatedItem,
|
||||||
trait_item_span: Option<Span>)
|
trait_item_span: Option<Span>)
|
||||||
-> Result<(), ErrorReported> {
|
-> Result<(), ErrorReported> {
|
||||||
let m_fty = |method: &ty::AssociatedItem| {
|
let impl_m_fty = tcx.fn_sig(impl_m.def_id);
|
||||||
match tcx.type_of(method.def_id).sty {
|
let trait_m_fty = tcx.fn_sig(trait_m.def_id);
|
||||||
ty::TyFnDef(_, _, f) => f,
|
|
||||||
_ => bug!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let impl_m_fty = m_fty(impl_m);
|
|
||||||
let trait_m_fty = m_fty(trait_m);
|
|
||||||
let trait_number_args = trait_m_fty.inputs().skip_binder().len();
|
let trait_number_args = trait_m_fty.inputs().skip_binder().len();
|
||||||
let impl_number_args = impl_m_fty.inputs().skip_binder().len();
|
let impl_number_args = impl_m_fty.inputs().skip_binder().len();
|
||||||
if trait_number_args != impl_number_args {
|
if trait_number_args != impl_number_args {
|
||||||
|
@ -143,12 +143,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn has_no_input_arg(&self, method: &AssociatedItem) -> bool {
|
fn has_no_input_arg(&self, method: &AssociatedItem) -> bool {
|
||||||
match method.def() {
|
match method.def() {
|
||||||
Def::Method(def_id) => {
|
Def::Method(def_id) => {
|
||||||
match self.tcx.type_of(def_id).sty {
|
self.tcx.fn_sig(def_id).inputs().skip_binder().len() == 1
|
||||||
ty::TypeVariants::TyFnDef(_, _, sig) => {
|
|
||||||
sig.inputs().skip_binder().len() == 1
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
use intrinsics;
|
use intrinsics;
|
||||||
use rustc::traits::{ObligationCause, ObligationCauseCode};
|
use rustc::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc::ty::subst::Substs;
|
|
||||||
use rustc::ty::{self, TyCtxt, Ty};
|
use rustc::ty::{self, TyCtxt, Ty};
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use require_same_types;
|
use require_same_types;
|
||||||
@ -35,22 +34,22 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
output: Ty<'tcx>) {
|
output: Ty<'tcx>) {
|
||||||
let def_id = tcx.hir.local_def_id(it.id);
|
let def_id = tcx.hir.local_def_id(it.id);
|
||||||
|
|
||||||
let substs = Substs::for_item(tcx, def_id,
|
match it.node {
|
||||||
|_, _| tcx.types.re_erased,
|
hir::ForeignItemFn(..) => {}
|
||||||
|def, _| tcx.mk_param_from_def(def));
|
_ => {
|
||||||
|
struct_span_err!(tcx.sess, it.span, E0619,
|
||||||
|
"intrinsic must be a function")
|
||||||
|
.span_label(it.span, "expected a function")
|
||||||
|
.emit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let fty = tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
|
|
||||||
inputs.into_iter(),
|
|
||||||
output,
|
|
||||||
false,
|
|
||||||
hir::Unsafety::Unsafe,
|
|
||||||
abi
|
|
||||||
)));
|
|
||||||
let i_n_tps = tcx.generics_of(def_id).types.len();
|
let i_n_tps = tcx.generics_of(def_id).types.len();
|
||||||
if i_n_tps != n_tps {
|
if i_n_tps != n_tps {
|
||||||
let span = match it.node {
|
let span = match it.node {
|
||||||
hir::ForeignItemFn(_, _, ref generics) => generics.span,
|
hir::ForeignItemFn(_, _, ref generics) => generics.span,
|
||||||
hir::ForeignItemStatic(..) => it.span
|
_ => bug!()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct_span_err!(tcx.sess, span, E0094,
|
struct_span_err!(tcx.sess, span, E0094,
|
||||||
@ -59,14 +58,18 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
i_n_tps, n_tps)
|
i_n_tps, n_tps)
|
||||||
.span_label(span, format!("expected {} type parameter", n_tps))
|
.span_label(span, format!("expected {} type parameter", n_tps))
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
return;
|
||||||
require_same_types(tcx,
|
|
||||||
&ObligationCause::new(it.span,
|
|
||||||
it.id,
|
|
||||||
ObligationCauseCode::IntrinsicType),
|
|
||||||
tcx.type_of(def_id),
|
|
||||||
fty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
|
||||||
|
inputs.into_iter(),
|
||||||
|
output,
|
||||||
|
false,
|
||||||
|
hir::Unsafety::Unsafe,
|
||||||
|
abi
|
||||||
|
)));
|
||||||
|
let cause = ObligationCause::new(it.span, it.id, ObligationCauseCode::IntrinsicType);
|
||||||
|
require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
|
/// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
|
||||||
@ -376,7 +379,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
let mut structural_to_nomimal = FxHashMap();
|
let mut structural_to_nomimal = FxHashMap();
|
||||||
|
|
||||||
let sig = tcx.type_of(def_id).fn_sig();
|
let sig = tcx.fn_sig(def_id);
|
||||||
let sig = tcx.no_late_bound_regions(&sig).unwrap();
|
let sig = tcx.no_late_bound_regions(&sig).unwrap();
|
||||||
if intr.inputs.len() != sig.inputs().len() {
|
if intr.inputs.len() != sig.inputs().len() {
|
||||||
span_err!(tcx.sess, it.span, E0444,
|
span_err!(tcx.sess, it.span, E0444,
|
||||||
|
@ -375,7 +375,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
debug!("method_predicates after subst = {:?}", method_predicates);
|
debug!("method_predicates after subst = {:?}", method_predicates);
|
||||||
|
|
||||||
let sig = self.tcx.type_of(def_id).fn_sig();
|
let sig = self.tcx.fn_sig(def_id);
|
||||||
|
|
||||||
// Instantiate late-bound regions and substitute the trait
|
// Instantiate late-bound regions and substitute the trait
|
||||||
// parameters into the method type to get the actual method type.
|
// parameters into the method type to get the actual method type.
|
||||||
|
@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// NB: Instantiate late-bound regions first so that
|
// NB: Instantiate late-bound regions first so that
|
||||||
// `instantiate_type_scheme` can normalize associated types that
|
// `instantiate_type_scheme` can normalize associated types that
|
||||||
// may reference those regions.
|
// may reference those regions.
|
||||||
let fn_sig = tcx.type_of(def_id).fn_sig();
|
let fn_sig = tcx.fn_sig(def_id);
|
||||||
let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
|
let fn_sig = self.replace_late_bound_regions_with_fresh_var(span,
|
||||||
infer::FnCall,
|
infer::FnCall,
|
||||||
&fn_sig).0;
|
&fn_sig).0;
|
||||||
|
@ -673,7 +673,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
expected: ty::Ty<'tcx>) -> bool {
|
expected: ty::Ty<'tcx>) -> bool {
|
||||||
match method.def() {
|
match method.def() {
|
||||||
Def::Method(def_id) => {
|
Def::Method(def_id) => {
|
||||||
let fty = self.tcx.type_of(def_id).fn_sig();
|
let fty = self.tcx.fn_sig(def_id);
|
||||||
self.probe(|_| {
|
self.probe(|_| {
|
||||||
let substs = self.fresh_substs_for_item(self.span, method.def_id);
|
let substs = self.fresh_substs_for_item(self.span, method.def_id);
|
||||||
let output = fty.output().subst(self.tcx, substs);
|
let output = fty.output().subst(self.tcx, substs);
|
||||||
@ -1288,7 +1288,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
impl_ty: Ty<'tcx>,
|
impl_ty: Ty<'tcx>,
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> Ty<'tcx> {
|
-> Ty<'tcx> {
|
||||||
let self_ty = self.tcx.type_of(method).fn_sig().input(0);
|
let self_ty = self.tcx.fn_sig(method).input(0);
|
||||||
debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})",
|
debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})",
|
||||||
impl_ty,
|
impl_ty,
|
||||||
self_ty,
|
self_ty,
|
||||||
|
@ -718,20 +718,12 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
typeck_item_bodies,
|
typeck_item_bodies,
|
||||||
typeck_tables_of,
|
typeck_tables_of,
|
||||||
has_typeck_tables,
|
has_typeck_tables,
|
||||||
fn_sig,
|
|
||||||
closure_kind,
|
closure_kind,
|
||||||
adt_destructor,
|
adt_destructor,
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
def_id: DefId)
|
|
||||||
-> ty::PolyFnSig<'tcx> {
|
|
||||||
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
|
||||||
tcx.typeck_tables_of(def_id).closure_tys[&node_id]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
def_id: DefId)
|
def_id: DefId)
|
||||||
-> ty::ClosureKind {
|
-> ty::ClosureKind {
|
||||||
@ -844,7 +836,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
Inherited::build(tcx, def_id).enter(|inh| {
|
Inherited::build(tcx, def_id).enter(|inh| {
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
let fcx = if let Some(decl) = fn_decl {
|
let fcx = if let Some(decl) = fn_decl {
|
||||||
let fn_sig = tcx.type_of(def_id).fn_sig();
|
let fn_sig = tcx.fn_sig(def_id);
|
||||||
|
|
||||||
check_abi(tcx, span, fn_sig.abi());
|
check_abi(tcx, span, fn_sig.abi());
|
||||||
|
|
||||||
@ -2173,7 +2165,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
-> ty::TypeAndMut<'tcx>
|
-> ty::TypeAndMut<'tcx>
|
||||||
{
|
{
|
||||||
// extract method return type, which will be &T;
|
// extract method return type, which will be &T;
|
||||||
// all LB regions should have been instantiated during method lookup
|
|
||||||
let ret_ty = method.sig.output();
|
let ret_ty = method.sig.output();
|
||||||
|
|
||||||
// method returns &T, but the type as visible to user is T, so deref
|
// method returns &T, but the type as visible to user is T, so deref
|
||||||
@ -2580,8 +2571,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
|
ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
|
||||||
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
|
variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
|
||||||
}
|
}
|
||||||
ty::TyFnDef(.., f) => {
|
ty::TyFnDef(..) => {
|
||||||
let ptr_ty = self.tcx.mk_fn_ptr(f);
|
let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
|
||||||
let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
|
let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
|
||||||
variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
|
variadic_error(tcx.sess, arg.span, arg_ty, &format!("{}", ptr_ty));
|
||||||
}
|
}
|
||||||
|
@ -177,12 +177,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
|||||||
}
|
}
|
||||||
ty::AssociatedKind::Method => {
|
ty::AssociatedKind::Method => {
|
||||||
reject_shadowing_type_parameters(fcx.tcx, item.def_id);
|
reject_shadowing_type_parameters(fcx.tcx, item.def_id);
|
||||||
let method_ty = fcx.tcx.type_of(item.def_id);
|
let sig = fcx.tcx.fn_sig(item.def_id);
|
||||||
let method_ty = fcx.normalize_associated_types_in(span, &method_ty);
|
let sig = fcx.normalize_associated_types_in(span, &sig);
|
||||||
let predicates = fcx.tcx.predicates_of(item.def_id)
|
let predicates = fcx.tcx.predicates_of(item.def_id)
|
||||||
.instantiate_identity(fcx.tcx);
|
.instantiate_identity(fcx.tcx);
|
||||||
let predicates = fcx.normalize_associated_types_in(span, &predicates);
|
let predicates = fcx.normalize_associated_types_in(span, &predicates);
|
||||||
let sig = method_ty.fn_sig();
|
|
||||||
this.check_fn_or_method(fcx, span, sig, &predicates,
|
this.check_fn_or_method(fcx, span, sig, &predicates,
|
||||||
item.def_id, &mut implied_bounds);
|
item.def_id, &mut implied_bounds);
|
||||||
let sig_if_method = sig_if_method.expect("bad signature for method");
|
let sig_if_method = sig_if_method.expect("bad signature for method");
|
||||||
@ -331,9 +330,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
|||||||
fn check_item_fn(&mut self, item: &hir::Item) {
|
fn check_item_fn(&mut self, item: &hir::Item) {
|
||||||
self.for_item(item).with_fcx(|fcx, this| {
|
self.for_item(item).with_fcx(|fcx, this| {
|
||||||
let def_id = fcx.tcx.hir.local_def_id(item.id);
|
let def_id = fcx.tcx.hir.local_def_id(item.id);
|
||||||
let ty = fcx.tcx.type_of(def_id);
|
let sig = fcx.tcx.fn_sig(def_id);
|
||||||
let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
|
let sig = fcx.normalize_associated_types_in(item.span, &sig);
|
||||||
let sig = item_ty.fn_sig();
|
|
||||||
|
|
||||||
let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx);
|
let predicates = fcx.tcx.predicates_of(def_id).instantiate_identity(fcx.tcx);
|
||||||
let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
|
let predicates = fcx.normalize_associated_types_in(item.span, &predicates);
|
||||||
@ -461,9 +459,9 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
|||||||
|
|
||||||
let span = method_sig.decl.inputs[0].span;
|
let span = method_sig.decl.inputs[0].span;
|
||||||
|
|
||||||
let method_ty = fcx.tcx.type_of(method.def_id);
|
let sig = fcx.tcx.fn_sig(method.def_id);
|
||||||
let fty = fcx.normalize_associated_types_in(span, &method_ty);
|
let sig = fcx.normalize_associated_types_in(span, &sig);
|
||||||
let sig = fcx.liberate_late_bound_regions(method.def_id, &fty.fn_sig());
|
let sig = fcx.liberate_late_bound_regions(method.def_id, &sig);
|
||||||
|
|
||||||
debug!("check_method_receiver: sig={:?}", sig);
|
debug!("check_method_receiver: sig={:?}", sig);
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
type_param_predicates,
|
type_param_predicates,
|
||||||
trait_def,
|
trait_def,
|
||||||
adt_def,
|
adt_def,
|
||||||
|
fn_sig,
|
||||||
impl_trait_ref,
|
impl_trait_ref,
|
||||||
impl_polarity,
|
impl_polarity,
|
||||||
is_foreign_item,
|
is_foreign_item,
|
||||||
@ -447,6 +448,9 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
|
|||||||
tcx.generics_of(def_id);
|
tcx.generics_of(def_id);
|
||||||
tcx.type_of(def_id);
|
tcx.type_of(def_id);
|
||||||
tcx.predicates_of(def_id);
|
tcx.predicates_of(def_id);
|
||||||
|
if let hir::ForeignItemFn(..) = item.node {
|
||||||
|
tcx.fn_sig(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemEnum(ref enum_definition, _) => {
|
hir::ItemEnum(ref enum_definition, _) => {
|
||||||
@ -497,6 +501,9 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) {
|
|||||||
tcx.generics_of(def_id);
|
tcx.generics_of(def_id);
|
||||||
tcx.type_of(def_id);
|
tcx.type_of(def_id);
|
||||||
tcx.predicates_of(def_id);
|
tcx.predicates_of(def_id);
|
||||||
|
if let hir::ItemFn(..) = it.node {
|
||||||
|
tcx.fn_sig(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,6 +518,9 @@ fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: ast:
|
|||||||
hir::TraitItemKind::Type(_, Some(_)) |
|
hir::TraitItemKind::Type(_, Some(_)) |
|
||||||
hir::TraitItemKind::Method(..) => {
|
hir::TraitItemKind::Method(..) => {
|
||||||
tcx.type_of(def_id);
|
tcx.type_of(def_id);
|
||||||
|
if let hir::TraitItemKind::Method(..) = trait_item.node {
|
||||||
|
tcx.fn_sig(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::TraitItemKind::Type(_, None) => {}
|
hir::TraitItemKind::Type(_, None) => {}
|
||||||
@ -524,6 +534,9 @@ fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_id: ast::N
|
|||||||
tcx.generics_of(def_id);
|
tcx.generics_of(def_id);
|
||||||
tcx.type_of(def_id);
|
tcx.type_of(def_id);
|
||||||
tcx.predicates_of(def_id);
|
tcx.predicates_of(def_id);
|
||||||
|
if let hir::ImplItemKind::Method(..) = tcx.hir.expect_impl_item(impl_item_id).node {
|
||||||
|
tcx.fn_sig(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
@ -963,10 +976,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
match tcx.hir.get(node_id) {
|
match tcx.hir.get(node_id) {
|
||||||
NodeTraitItem(item) => {
|
NodeTraitItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
TraitItemKind::Method(ref sig, _) => {
|
TraitItemKind::Method(..) => {
|
||||||
let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
|
|
||||||
let substs = Substs::identity_for_item(tcx, def_id);
|
let substs = Substs::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs, fty)
|
tcx.mk_fn_def(def_id, substs)
|
||||||
}
|
}
|
||||||
TraitItemKind::Const(ref ty, _) |
|
TraitItemKind::Const(ref ty, _) |
|
||||||
TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
|
TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
|
||||||
@ -978,10 +990,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
NodeImplItem(item) => {
|
NodeImplItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
ImplItemKind::Method(ref sig, _) => {
|
ImplItemKind::Method(..) => {
|
||||||
let fty = AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl);
|
|
||||||
let substs = Substs::identity_for_item(tcx, def_id);
|
let substs = Substs::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs, fty)
|
tcx.mk_fn_def(def_id, substs)
|
||||||
}
|
}
|
||||||
ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
|
ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
|
||||||
ImplItemKind::Type(ref ty) => {
|
ImplItemKind::Type(ref ty) => {
|
||||||
@ -1001,10 +1012,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
|
ItemTy(ref t, _) | ItemImpl(.., ref t, _) => {
|
||||||
icx.to_ty(t)
|
icx.to_ty(t)
|
||||||
}
|
}
|
||||||
ItemFn(ref decl, unsafety, _, abi, _, _) => {
|
ItemFn(..) => {
|
||||||
let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl);
|
|
||||||
let substs = Substs::identity_for_item(tcx, def_id);
|
let substs = Substs::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs, tofd)
|
tcx.mk_fn_def(def_id, substs)
|
||||||
}
|
}
|
||||||
ItemEnum(..) |
|
ItemEnum(..) |
|
||||||
ItemStruct(..) |
|
ItemStruct(..) |
|
||||||
@ -1029,11 +1039,10 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NodeForeignItem(foreign_item) => {
|
NodeForeignItem(foreign_item) => {
|
||||||
let abi = tcx.hir.get_foreign_abi(node_id);
|
|
||||||
|
|
||||||
match foreign_item.node {
|
match foreign_item.node {
|
||||||
ForeignItemFn(ref fn_decl, _, _) => {
|
ForeignItemFn(..) => {
|
||||||
compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
|
let substs = Substs::identity_for_item(tcx, def_id);
|
||||||
|
tcx.mk_fn_def(def_id, substs)
|
||||||
}
|
}
|
||||||
ForeignItemStatic(ref t, _) => icx.to_ty(t)
|
ForeignItemStatic(ref t, _) => icx.to_ty(t)
|
||||||
}
|
}
|
||||||
@ -1041,21 +1050,13 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
NodeStructCtor(&ref def) |
|
NodeStructCtor(&ref def) |
|
||||||
NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
|
NodeVariant(&Spanned { node: hir::Variant_ { data: ref def, .. }, .. }) => {
|
||||||
let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
|
|
||||||
match *def {
|
match *def {
|
||||||
VariantData::Unit(..) | VariantData::Struct(..) => ty,
|
VariantData::Unit(..) | VariantData::Struct(..) => {
|
||||||
VariantData::Tuple(ref fields, _) => {
|
tcx.type_of(tcx.hir.get_parent_did(node_id))
|
||||||
let inputs = fields.iter().map(|f| {
|
}
|
||||||
tcx.type_of(tcx.hir.local_def_id(f.id))
|
VariantData::Tuple(..) => {
|
||||||
});
|
|
||||||
let substs = Substs::identity_for_item(tcx, def_id);
|
let substs = Substs::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs, ty::Binder(tcx.mk_fn_sig(
|
tcx.mk_fn_def(def_id, substs)
|
||||||
inputs,
|
|
||||||
ty,
|
|
||||||
false,
|
|
||||||
hir::Unsafety::Normal,
|
|
||||||
abi::Abi::Rust
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1105,6 +1106,58 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
def_id: DefId)
|
||||||
|
-> ty::PolyFnSig<'tcx> {
|
||||||
|
use rustc::hir::map::*;
|
||||||
|
use rustc::hir::*;
|
||||||
|
|
||||||
|
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
|
|
||||||
|
let icx = ItemCtxt::new(tcx, def_id);
|
||||||
|
|
||||||
|
match tcx.hir.get(node_id) {
|
||||||
|
NodeTraitItem(&hir::TraitItem { node: TraitItemKind::Method(ref sig, _), .. }) |
|
||||||
|
NodeImplItem(&hir::ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) => {
|
||||||
|
AstConv::ty_of_fn(&icx, sig.unsafety, sig.abi, &sig.decl)
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem(&hir::Item { node: ItemFn(ref decl, unsafety, _, abi, _, _), .. }) => {
|
||||||
|
AstConv::ty_of_fn(&icx, unsafety, abi, decl)
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeForeignItem(&hir::ForeignItem { node: ForeignItemFn(ref fn_decl, _, _), .. }) => {
|
||||||
|
let abi = tcx.hir.get_foreign_abi(node_id);
|
||||||
|
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeStructCtor(&VariantData::Tuple(ref fields, _)) |
|
||||||
|
NodeVariant(&Spanned { node: hir::Variant_ {
|
||||||
|
data: VariantData::Tuple(ref fields, _), ..
|
||||||
|
}, .. }) => {
|
||||||
|
let ty = tcx.type_of(tcx.hir.get_parent_did(node_id));
|
||||||
|
let inputs = fields.iter().map(|f| {
|
||||||
|
tcx.type_of(tcx.hir.local_def_id(f.id))
|
||||||
|
});
|
||||||
|
ty::Binder(tcx.mk_fn_sig(
|
||||||
|
inputs,
|
||||||
|
ty,
|
||||||
|
false,
|
||||||
|
hir::Unsafety::Normal,
|
||||||
|
abi::Abi::Rust
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
|
||||||
|
tcx.typeck_tables_of(def_id).closure_tys[&node_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
x => {
|
||||||
|
bug!("unexpected sort of node in fn_sig(): {:?}", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn impl_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
def_id: DefId)
|
def_id: DefId)
|
||||||
-> Option<ty::TraitRef<'tcx>> {
|
-> Option<ty::TraitRef<'tcx>> {
|
||||||
@ -1502,12 +1555,12 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
|
fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
decl: &hir::FnDecl,
|
decl: &hir::FnDecl,
|
||||||
abi: abi::Abi)
|
abi: abi::Abi)
|
||||||
-> Ty<'tcx>
|
-> ty::PolyFnSig<'tcx>
|
||||||
{
|
{
|
||||||
let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
|
let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl);
|
||||||
|
|
||||||
@ -1533,8 +1586,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let substs = Substs::identity_for_item(tcx, def_id);
|
fty
|
||||||
tcx.mk_fn_def(def_id, substs, fty)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
@ -4736,4 +4736,5 @@ register_diagnostics! {
|
|||||||
E0568, // auto-traits can not have predicates,
|
E0568, // auto-traits can not have predicates,
|
||||||
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
|
E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
|
||||||
E0592, // duplicate definitions with name `{}`
|
E0592, // duplicate definitions with name `{}`
|
||||||
|
E0619, // intrinsic must be a function
|
||||||
}
|
}
|
||||||
|
@ -198,22 +198,21 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
}
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
let substs = tcx.intern_substs(&[]);
|
let se_ty = tcx.mk_fn_ptr(ty::Binder(
|
||||||
let se_ty = tcx.mk_fn_def(main_def_id, substs,
|
tcx.mk_fn_sig(
|
||||||
ty::Binder(tcx.mk_fn_sig(
|
|
||||||
iter::empty(),
|
iter::empty(),
|
||||||
tcx.mk_nil(),
|
tcx.mk_nil(),
|
||||||
false,
|
false,
|
||||||
hir::Unsafety::Normal,
|
hir::Unsafety::Normal,
|
||||||
Abi::Rust
|
Abi::Rust
|
||||||
))
|
)
|
||||||
);
|
));
|
||||||
|
|
||||||
require_same_types(
|
require_same_types(
|
||||||
tcx,
|
tcx,
|
||||||
&ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
|
&ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType),
|
||||||
se_ty,
|
se_ty,
|
||||||
main_t);
|
tcx.mk_fn_ptr(tcx.fn_sig(main_def_id)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(main_span,
|
span_bug!(main_span,
|
||||||
@ -248,9 +247,8 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
let substs = tcx.intern_substs(&[]);
|
let se_ty = tcx.mk_fn_ptr(ty::Binder(
|
||||||
let se_ty = tcx.mk_fn_def(start_def_id, substs,
|
tcx.mk_fn_sig(
|
||||||
ty::Binder(tcx.mk_fn_sig(
|
|
||||||
[
|
[
|
||||||
tcx.types.isize,
|
tcx.types.isize,
|
||||||
tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
|
tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))
|
||||||
@ -259,14 +257,14 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
false,
|
false,
|
||||||
hir::Unsafety::Normal,
|
hir::Unsafety::Normal,
|
||||||
Abi::Rust
|
Abi::Rust
|
||||||
))
|
)
|
||||||
);
|
));
|
||||||
|
|
||||||
require_same_types(
|
require_same_types(
|
||||||
tcx,
|
tcx,
|
||||||
&ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
|
&ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType),
|
||||||
se_ty,
|
se_ty,
|
||||||
start_t);
|
tcx.mk_fn_ptr(tcx.fn_sig(start_def_id)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(start_span,
|
span_bug!(start_span,
|
||||||
|
@ -382,6 +382,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
// leaf type -- noop
|
// leaf type -- noop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::TyFnDef(..) |
|
||||||
ty::TyClosure(..) |
|
ty::TyClosure(..) |
|
||||||
ty::TyAnon(..) => {
|
ty::TyAnon(..) => {
|
||||||
bug!("Unexpected closure type in variance computation");
|
bug!("Unexpected closure type in variance computation");
|
||||||
@ -466,7 +467,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::TyFnDef(.., sig) |
|
|
||||||
ty::TyFnPtr(sig) => {
|
ty::TyFnPtr(sig) => {
|
||||||
self.add_constraints_from_sig(current, sig, variance);
|
self.add_constraints_from_sig(current, sig, variance);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
|
fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
|
||||||
let sig = cx.tcx.type_of(did).fn_sig();
|
let sig = cx.tcx.fn_sig(did);
|
||||||
|
|
||||||
let constness = if cx.tcx.is_const_fn(did) {
|
let constness = if cx.tcx.is_const_fn(did) {
|
||||||
hir::Constness::Const
|
hir::Constness::Const
|
||||||
|
@ -1367,7 +1367,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
|||||||
ty::AssociatedKind::Method => {
|
ty::AssociatedKind::Method => {
|
||||||
let generics = (cx.tcx.generics_of(self.def_id),
|
let generics = (cx.tcx.generics_of(self.def_id),
|
||||||
&cx.tcx.predicates_of(self.def_id)).clean(cx);
|
&cx.tcx.predicates_of(self.def_id)).clean(cx);
|
||||||
let sig = cx.tcx.type_of(self.def_id).fn_sig();
|
let sig = cx.tcx.fn_sig(self.def_id);
|
||||||
let mut decl = (self.def_id, sig).clean(cx);
|
let mut decl = (self.def_id, sig).clean(cx);
|
||||||
|
|
||||||
if self.method_has_self_argument {
|
if self.method_has_self_argument {
|
||||||
@ -1842,17 +1842,21 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||||||
mutability: mt.mutbl.clean(cx),
|
mutability: mt.mutbl.clean(cx),
|
||||||
type_: box mt.ty.clean(cx),
|
type_: box mt.ty.clean(cx),
|
||||||
},
|
},
|
||||||
ty::TyFnDef(.., sig) |
|
ty::TyFnDef(..) |
|
||||||
ty::TyFnPtr(sig) => BareFunction(box BareFunctionDecl {
|
ty::TyFnPtr(_) => {
|
||||||
unsafety: sig.unsafety(),
|
let ty = cx.tcx.lift(self).unwrap();
|
||||||
generics: Generics {
|
let sig = ty.fn_sig(cx.tcx);
|
||||||
lifetimes: Vec::new(),
|
BareFunction(box BareFunctionDecl {
|
||||||
type_params: Vec::new(),
|
unsafety: sig.unsafety(),
|
||||||
where_predicates: Vec::new()
|
generics: Generics {
|
||||||
},
|
lifetimes: Vec::new(),
|
||||||
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
|
type_params: Vec::new(),
|
||||||
abi: sig.abi(),
|
where_predicates: Vec::new()
|
||||||
}),
|
},
|
||||||
|
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
|
||||||
|
abi: sig.abi(),
|
||||||
|
})
|
||||||
|
}
|
||||||
ty::TyAdt(def, substs) => {
|
ty::TyAdt(def, substs) => {
|
||||||
let did = def.did;
|
let did = def.did;
|
||||||
let kind = match def.adt_kind() {
|
let kind = match def.adt_kind() {
|
||||||
|
@ -11,6 +11,6 @@
|
|||||||
#![feature(intrinsics)]
|
#![feature(intrinsics)]
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
pub static breakpoint : unsafe extern "rust-intrinsic" fn();
|
pub static breakpoint : unsafe extern "rust-intrinsic" fn();
|
||||||
//~^ ERROR intrinsic has wrong type
|
//~^ ERROR intrinsic must be a function
|
||||||
}
|
}
|
||||||
fn main() { unsafe { breakpoint(); } }
|
fn main() { unsafe { breakpoint(); } }
|
||||||
|
Loading…
Reference in New Issue
Block a user