Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rustc: move the PolyFnSig out of TyFnDef.
  • Loading branch information
eddyb committed Jun 27, 2017
commit 33ecf72e8e26b5bf5449ae27297e83c9f78aa3ad
3 changes: 1 addition & 2 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,9 @@ for ty::TypeVariants<'tcx>
region.hash_stable(hcx, hasher);
pointee_ty.hash_stable(hcx, hasher);
}
TyFnDef(def_id, substs, ref sig) => {
TyFnDef(def_id, substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
sig.hash_stable(hcx, hasher);
}
TyFnPtr(ref sig) => {
sig.hash_stable(hcx, hasher);
Expand Down
28 changes: 13 additions & 15 deletions src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! `unsafe`.
use self::RootUnsafeContext::*;

use ty::{self, Ty, TyCtxt};
use ty::{self, TyCtxt};
use lint;

use syntax::ast;
Expand Down Expand Up @@ -40,14 +40,6 @@ enum RootUnsafeContext {
UnsafeBlock(ast::NodeId),
}

fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::TyFnDef(.., f) |
ty::TyFnPtr(f) => f.unsafety() == hir::Unsafety::Unsafe,
_ => false,
}
}

struct EffectCheckVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
Expand Down Expand Up @@ -174,10 +166,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
match expr.node {
hir::ExprMethodCall(..) => {
let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
let base_type = self.tcx.type_of(def_id);
debug!("effect: method call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
let sig = self.tcx.fn_sig(def_id);
debug!("effect: method call case, signature is {:?}",
sig);

if sig.0.unsafety == hir::Unsafety::Unsafe {
self.require_unsafe(expr.span,
"invocation of unsafe method")
}
Expand All @@ -186,8 +179,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
let base_type = self.tables.expr_ty_adjusted(base);
debug!("effect: call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
self.require_unsafe(expr.span, "call to unsafe function")
match base_type.sty {
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
if base_type.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
self.require_unsafe(expr.span, "call to unsafe function")
}
}
_ => {}
}
}
hir::ExprUnary(hir::UnDeref, ref base) => {
Expand Down
27 changes: 8 additions & 19 deletions src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,8 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
let intrinsic = match self.tcx.type_of(def_id).sty {
ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic,
_ => return false
};
intrinsic && self.tcx.item_name(def_id) == "transmute"
self.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
self.tcx.item_name(def_id) == "transmute"
}

fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
Expand Down Expand Up @@ -153,22 +150,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
} else {
Def::Err
};
match def {
Def::Fn(did) if self.def_id_is_transmute(did) => {
if let Def::Fn(did) = def {
if self.def_id_is_transmute(did) {
let typ = self.tables.node_id_to_type(expr.id);
let typ = self.tcx.lift_to_global(&typ).unwrap();
match typ.sty {
ty::TyFnDef(.., sig) if sig.abi() == RustIntrinsic => {
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();
self.check_transmute(expr.span, from, to);
}
_ => {
span_bug!(expr.span, "transmute wasn't a bare fn?!");
}
}
let sig = typ.fn_sig(self.tcx);
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();
self.check_transmute(expr.span, from, to);
}
_ => {}
}

intravisit::walk_expr(self, expr);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

// The `Self` type is erased, so it should not appear in list of
// arguments or return type apart from the receiver.
let ref sig = self.type_of(method.def_id).fn_sig();
let ref sig = self.fn_sig(method.def_id);
for input_ty in &sig.skip_binder().inputs()[1..] {
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
return Some(MethodViolationCode::ReferencesSelf);
Expand Down
12 changes: 11 additions & 1 deletion src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1137,9 +1137,19 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
-> Progress<'tcx>
{
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
let sig = fn_type.fn_sig();
let sig = fn_type.fn_sig(selcx.tcx());
let Normalized {
value: sig,
obligations
} = normalize_with_depth(selcx,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth+1,
&sig);

confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
.with_addl_obligations(fn_pointer_vtable.nested)
.with_addl_obligations(obligations)
}

fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
Expand Down
33 changes: 18 additions & 15 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1404,19 +1404,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}

// provide an impl, but only for suitable `fn` pointers
ty::TyFnDef(.., ty::Binder(ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
variadic: false,
..
})) |
ty::TyFnPtr(ty::Binder(ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
variadic: false,
..
})) => {
candidates.vec.push(FnPointerCandidate);
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
if let ty::Binder(ty::FnSig {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
variadic: false,
..
}) = self_ty.fn_sig(self.tcx()) {
candidates.vec.push(FnPointerCandidate);
}
}

_ => { }
Expand Down Expand Up @@ -2348,19 +2344,26 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {

// ok to skip binder; it is reintroduced below
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
let sig = self_ty.fn_sig();
let sig = self_ty.fn_sig(self.tcx());
let trait_ref =
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
self_ty,
sig,
util::TupleArgumentsFlag::Yes)
.map_bound(|(trait_ref, _)| trait_ref);

let Normalized { value: trait_ref, obligations } =
project::normalize_with_depth(self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
&trait_ref);

self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?;
Ok(VtableFnPointerData { fn_ty: self_ty, nested: vec![] })
Ok(VtableFnPointerData { fn_ty: self_ty, nested: obligations })
}

fn confirm_closure_candidate(&mut self,
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1378,9 +1378,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

pub fn mk_fn_def(self, def_id: DefId,
substs: &'tcx Substs<'tcx>,
fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnDef(def_id, substs, fty))
substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnDef(def_id, substs))
}

pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
// view of possibly unifying
simplify_type(tcx, mt.ty, can_simplify_params)
}
ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) => {
Some(ClosureSimplifiedType(def_id))
}
ty::TyNever => Some(NeverSimplifiedType),
ty::TyTuple(ref tys, _) => {
Some(TupleSimplifiedType(tys.len()))
}
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {
ty::TyFnPtr(ref f) => {
Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
}
ty::TyProjection(_) | ty::TyParam(_) => {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,8 @@ impl FlagComputation {
self.add_tys(&ts[..]);
}

&ty::TyFnDef(_, substs, f) => {
&ty::TyFnDef(_, substs) => {
self.add_substs(substs);
self.add_fn_sig(f);
}

&ty::TyFnPtr(f) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/item_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
.filter_map(|ty| characteristic_def_id_of_type(ty))
.next(),

ty::TyFnDef(def_id, ..) |
ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) => Some(def_id),

ty::TyBool |
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl AssociatedItem {
// late-bound regions, and we don't want method signatures to show up
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
// regions just fine, showing `fn(&MyType)`.
format!("{}", tcx.type_of(self.def_id).fn_sig().skip_binder())
format!("{}", tcx.fn_sig(self.def_id).skip_binder())
}
ty::AssociatedKind::Type => format!("type {};", self.name.to_string()),
ty::AssociatedKind::Const => {
Expand Down
6 changes: 2 additions & 4 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,13 +440,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
}
}

(&ty::TyFnDef(a_def_id, a_substs, a_fty),
&ty::TyFnDef(b_def_id, b_substs, b_fty))
(&ty::TyFnDef(a_def_id, a_substs), &ty::TyFnDef(b_def_id, b_substs))
if a_def_id == b_def_id =>
{
let substs = relate_substs(relation, None, a_substs, b_substs)?;
let fty = relation.relate(&a_fty, &b_fty)?;
Ok(tcx.mk_fn_def(a_def_id, substs, fty))
Ok(tcx.mk_fn_def(a_def_id, substs))
}

(&ty::TyFnPtr(a_fty), &ty::TyFnPtr(b_fty)) =>
Expand Down
10 changes: 3 additions & 7 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyDynamic(ref trait_ty, ref region) =>
ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
ty::TyFnDef(def_id, substs, f) => {
ty::TyFnDef(def_id,
substs.fold_with(folder),
f.fold_with(folder))
ty::TyFnDef(def_id, substs) => {
ty::TyFnDef(def_id, substs.fold_with(folder))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it okay that signatures are not folded anymore? (Is it possible to fold something kept in the tables at all?)
It would be really nice if they were at least still visited by default.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole point (which I'll try to describe once I'm sure there's no fatal flaw with the approach) is to reduce the amount of work done for these types. Anything that relied on seeing the signature has to visit it manually. It's not a property of the type and it was never meant to be, it's just one way to use values of that type (i.e. calling them).

}
ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
ty::TyRef(ref r, tm) => {
Expand Down Expand Up @@ -568,9 +566,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyDynamic(ref trait_ty, ref reg) =>
trait_ty.visit_with(visitor) || reg.visit_with(visitor),
ty::TyTuple(ts, _) => ts.visit_with(visitor),
ty::TyFnDef(_, substs, ref f) => {
substs.visit_with(visitor) || f.visit_with(visitor)
}
ty::TyFnDef(_, substs) => substs.visit_with(visitor),
ty::TyFnPtr(ref f) => f.visit_with(visitor),
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
Expand Down
11 changes: 7 additions & 4 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use hir::def_id::DefId;
use hir::map::DefPathHash;

use middle::region;
use ty::subst::Substs;
use ty::subst::{Substs, Subst};
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
use ty::{Slice, TyS};
use ty::subst::Kind;
Expand Down Expand Up @@ -138,7 +138,7 @@ pub enum TypeVariants<'tcx> {

/// The anonymous type of a function declaration/definition. Each
/// function has a unique type.
TyFnDef(DefId, &'tcx Substs<'tcx>, PolyFnSig<'tcx>),
TyFnDef(DefId, &'tcx Substs<'tcx>),

/// A pointer to a function. Written as `fn() -> i32`.
TyFnPtr(PolyFnSig<'tcx>),
Expand Down Expand Up @@ -1329,9 +1329,12 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
}

pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
pub fn fn_sig(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PolyFnSig<'tcx> {
match self.sty {
TyFnDef(.., f) | TyFnPtr(f) => f,
TyFnDef(def_id, substs) => {
tcx.fn_sig(def_id).subst(tcx, substs)
}
TyFnPtr(f) => f,
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
TyRef(_, m) => self.hash(m.mutbl),
TyClosure(def_id, _) |
TyAnon(def_id, _) |
TyFnDef(def_id, ..) => self.def_id(def_id),
TyFnDef(def_id, _) => self.def_id(def_id),
TyAdt(d, _) => self.def_id(d.did),
TyFnPtr(f) => {
self.hash(f.unsafety());
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
ty::TyTuple(ts, _) => {
stack.extend(ts.iter().cloned().rev());
}
ty::TyFnDef(_, substs, ft) => {
ty::TyFnDef(_, substs) => {
stack.extend(substs.types().rev());
push_sig_subtypes(stack, ft);
}
ty::TyFnPtr(ft) => {
push_sig_subtypes(stack, ft);
Expand Down
10 changes: 8 additions & 2 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,8 +753,14 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
}
write!(f, ")")
}
TyFnDef(def_id, substs, ref bare_fn) => {
write!(f, "{} {{", bare_fn.0)?;
TyFnDef(def_id, substs) => {
ty::tls::with(|tcx| {
let mut sig = tcx.fn_sig(def_id);
if let Some(substs) = tcx.lift(&substs) {
sig = sig.subst(tcx, substs);
}
write!(f, "{} {{", sig.0)
})?;
parameterized(f, substs, def_id, &[])?;
write!(f, "}}")
}
Expand Down
17 changes: 6 additions & 11 deletions src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,13 @@ fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
terminator: &'a Option<mir::Terminator<'tcx>>)
-> Option<(&'a [mir::Operand<'tcx>], Span)> {
if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
{
if let mir::Operand::Constant(ref func) = *oper
{
if let ty::TyFnDef(def_id, _, sig) = func.ty.sty
{
let abi = sig.abi();
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind {
if let mir::Operand::Constant(ref func) = *oper {
if let ty::TyFnDef(def_id, _) = func.ty.sty {
let abi = tcx.fn_sig(def_id).abi();
let name = tcx.item_name(def_id);
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
if name == "rustc_peek" {
return Some((args, source_info.span));
}
if abi == Abi::RustIntrinsic && name == "rustc_peek" {
return Some((args, source_info.span));
}
}
}
Expand Down
Loading