Skip to content

Commit

Permalink
Split TyBareFn into TyFnDef and TyFnPtr.
Browse files Browse the repository at this point in the history
There's a lot of stuff wrong with the representation of these types:
TyFnDef doesn't actually uniquely identify a function, TyFnPtr is used to
represent method calls, TyFnDef in the sub-expression of a cast isn't
correctly reified, and probably some other stuff I haven't discovered yet.
Splitting them seems like the right first step, though.
  • Loading branch information
eefriedman authored and eddyb committed Mar 9, 2016
1 parent 4b86841 commit b423a0f
Show file tree
Hide file tree
Showing 73 changed files with 406 additions and 324 deletions.
3 changes: 2 additions & 1 deletion src/librustc/middle/effect.rs
Expand Up @@ -44,7 +44,8 @@ enum RootUnsafeContext {

fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::TyBareFn(_, ref f) => f.unsafety == hir::Unsafety::Unsafe,
ty::TyFnDef(_, ref f) |
ty::TyFnPtr(ref f) => f.unsafety == hir::Unsafety::Unsafe,
_ => false,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -556,7 +556,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
callee, callee_ty);
let call_scope = self.tcx().region_maps.node_extent(call.id);
match callee_ty.sty {
ty::TyBareFn(..) => {
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
self.consume_expr(callee);
}
ty::TyError => { }
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/infer/freshen.rs
Expand Up @@ -161,7 +161,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
ty::TySlice(..) |
ty::TyRawPtr(..) |
ty::TyRef(..) |
ty::TyBareFn(..) |
ty::TyFnDef(..) |
ty::TyFnPtr(_) |
ty::TyTrait(..) |
ty::TyStruct(..) |
ty::TyClosure(..) |
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/intrinsicck.rs
Expand Up @@ -12,7 +12,7 @@ use dep_graph::DepNode;
use middle::def::Def;
use middle::def_id::DefId;
use middle::subst::{Subst, Substs, EnumeratedItems};
use middle::ty::{TransmuteRestriction, TyCtxt, TyBareFn};
use middle::ty::{TransmuteRestriction, TyCtxt};
use middle::ty::{self, Ty, TypeFoldable};

use std::fmt;
Expand Down Expand Up @@ -53,7 +53,7 @@ struct IntrinsicCheckingVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
let intrinsic = match self.tcx.lookup_item_type(def_id).ty.sty {
ty::TyBareFn(_, ref bfty) => bfty.abi == RustIntrinsic,
ty::TyFnDef(_, ref bfty) => bfty.abi == RustIntrinsic,
_ => return false
};
intrinsic && self.tcx.item_name(def_id).as_str() == "transmute"
Expand Down Expand Up @@ -238,7 +238,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
Def::Fn(did) if self.def_id_is_transmute(did) => {
let typ = self.tcx.node_id_to_type(expr.id);
match typ.sty {
TyBareFn(_, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
ty::TyFnDef(_, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
if let ty::FnConverging(to) = bare_fn_ty.sig.0.output {
let from = bare_fn_ty.sig.0.inputs[0];
self.check_transmute(expr.span, from, to, expr.id);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/traits/coherence.rs
Expand Up @@ -301,7 +301,8 @@ fn ty_is_local_constructor<'tcx>(tcx: &TyCtxt<'tcx>,
ty::TyUint(..) |
ty::TyFloat(..) |
ty::TyStr |
ty::TyBareFn(..) |
ty::TyFnDef(..) |
ty::TyFnPtr(_) |
ty::TyArray(..) |
ty::TySlice(..) |
ty::TyRawPtr(..) |
Expand Down
17 changes: 14 additions & 3 deletions src/librustc/middle/traits/select.rs
Expand Up @@ -1286,7 +1286,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}

// provide an impl, but only for suitable `fn` pointers
ty::TyBareFn(_, &ty::BareFnTy {
ty::TyFnDef(_, &ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: _,
output: ty::FnConverging(_),
variadic: false
})
}) |
ty::TyFnPtr(&ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
Expand Down Expand Up @@ -1646,7 +1655,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::TyInt(_) |
ty::TyBool |
ty::TyFloat(_) |
ty::TyBareFn(..) |
ty::TyFnDef(..) |
ty::TyFnPtr(_) |
ty::TyChar => {
// safe for everything
ok_if(Vec::new())
Expand Down Expand Up @@ -1850,7 +1860,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::TyInt(_) |
ty::TyBool |
ty::TyFloat(_) |
ty::TyBareFn(..) |
ty::TyFnDef(..) |
ty::TyFnPtr(_) |
ty::TyStr |
ty::TyError |
ty::TyInfer(ty::IntVar(_)) |
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/ty/adjustment.rs
Expand Up @@ -155,8 +155,8 @@ impl<'tcx> ty::TyS<'tcx> {
match *adjustment {
AdjustReifyFnPointer => {
match self.sty {
ty::TyBareFn(Some(_), b) => {
cx.mk_fn(None, b)
ty::TyFnDef(_, b) => {
cx.mk_ty(ty::TyFnPtr(b))
}
_ => {
cx.sess.bug(
Expand All @@ -168,7 +168,7 @@ impl<'tcx> ty::TyS<'tcx> {

AdjustUnsafeFnPointer => {
match self.sty {
ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
ty::TyFnPtr(b) => cx.safe_to_unsafe_fn_ty(b),
ref b => {
cx.sess.bug(
&format!("AdjustUnsafeFnPointer adjustment on non-fn-ptr: \
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/ty/cast.rs
Expand Up @@ -69,7 +69,9 @@ impl<'tcx> CastTy<'tcx> {
Some(CastTy::Int(IntTy::CEnum)),
ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)),
ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)),
ty::TyBareFn(..) => Some(CastTy::FnPtr),
// FIXME: Treating TyFnDef as a pointer here is a bit dubious;
// we should be coercing the operand to an actual pointer.
ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(CastTy::FnPtr),
_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/contents.rs
Expand Up @@ -187,7 +187,7 @@ impl<'tcx> ty::TyS<'tcx> {
// Scalar and unique types are sendable, and durable
ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) |
ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
ty::TyBareFn(..) | ty::TyChar => {
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar => {
TC::None
}

Expand Down
24 changes: 13 additions & 11 deletions src/librustc/middle/ty/context.rs
Expand Up @@ -734,8 +734,8 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn print_debug_stats(&self) {
sty_debug_print!(
self,
TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyBareFn, TyTrait,
TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr,
TyTrait, TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);

println!("Substs interner: #{}", self.substs_interner.borrow().len());
println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
Expand Down Expand Up @@ -792,12 +792,11 @@ impl<'tcx> TyCtxt<'tcx> {
/// Create an unsafe fn ty based on a safe fn ty.
pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
assert_eq!(bare_fn.unsafety, hir::Unsafety::Normal);
let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
self.mk_fn_ptr(ty::BareFnTy {
unsafety: hir::Unsafety::Unsafe,
abi: bare_fn.abi,
sig: bare_fn.sig.clone()
});
self.mk_fn(None, unsafe_fn_ty_a)
})
}

pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
Expand Down Expand Up @@ -946,26 +945,29 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(TyBool)
}

pub fn mk_fn(&self,
opt_def_id: Option<DefId>,
fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyBareFn(opt_def_id, fty))
pub fn mk_fn_def(&self, def_id: DefId,
fty: BareFnTy<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnDef(def_id, self.mk_bare_fn(fty)))
}

pub fn mk_fn_ptr(&self, fty: BareFnTy<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnPtr(self.mk_bare_fn(fty)))
}

pub fn mk_ctor_fn(&self,
def_id: DefId,
input_tys: &[Ty<'tcx>],
output: Ty<'tcx>) -> Ty<'tcx> {
let input_args = input_tys.iter().cloned().collect();
self.mk_fn(Some(def_id), self.mk_bare_fn(BareFnTy {
self.mk_fn_def(def_id, BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: input_args,
output: ty::FnConverging(output),
variadic: false
})
}))
})
}

pub fn mk_trait(&self,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/ty/error.rs
Expand Up @@ -223,8 +223,8 @@ impl<'tcx> ty::TyS<'tcx> {
ty::TySlice(_) => "slice".to_string(),
ty::TyRawPtr(_) => "*-ptr".to_string(),
ty::TyRef(_, _) => "&-ptr".to_string(),
ty::TyBareFn(Some(_), _) => format!("fn item"),
ty::TyBareFn(None, _) => "fn pointer".to_string(),
ty::TyFnDef(..) => format!("fn item"),
ty::TyFnPtr(_) => "fn pointer".to_string(),
ty::TyTrait(ref inner) => {
format!("trait {}", cx.item_path_str(inner.principal_def_id()))
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/fast_reject.rs
Expand Up @@ -83,7 +83,7 @@ pub fn simplify_type(tcx: &TyCtxt,
ty::TyTuple(ref tys) => {
Some(TupleSimplifiedType(tys.len()))
}
ty::TyBareFn(_, ref f) => {
ty::TyFnDef(_, ref f) | ty::TyFnPtr(ref f) => {
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
}
ty::TyProjection(_) | ty::TyParam(_) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/flags.rs
Expand Up @@ -134,7 +134,7 @@ impl FlagComputation {
self.add_tys(&ts[..]);
}

&ty::TyBareFn(_, ref f) => {
&ty::TyFnDef(_, ref f) | &ty::TyFnPtr(ref f) => {
self.add_fn_sig(&f.sig);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/ty/outlives.rs
Expand Up @@ -182,7 +182,8 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
ty::TyRawPtr(..) | // ...
ty::TyRef(..) | // OutlivesReference
ty::TyTuple(..) | // ...
ty::TyBareFn(..) | // OutlivesFunction (*)
ty::TyFnDef(..) | // OutlivesFunction (*)
ty::TyFnPtr(_) | // OutlivesFunction (*)
ty::TyTrait(..) | // OutlivesObject, OutlivesFragment (*)
ty::TyError => {
// (*) Bare functions and traits are both binders. In the
Expand Down
12 changes: 9 additions & 3 deletions src/librustc/middle/ty/relate.rs
Expand Up @@ -568,11 +568,17 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R,
}
}

(&ty::TyBareFn(a_opt_def_id, a_fty), &ty::TyBareFn(b_opt_def_id, b_fty))
if a_opt_def_id == b_opt_def_id =>
(&ty::TyFnDef(a_def_id, a_fty), &ty::TyFnDef(b_def_id, b_fty))
if a_def_id == b_def_id =>
{
let fty = try!(relation.relate(a_fty, b_fty));
Ok(tcx.mk_fn(a_opt_def_id, tcx.mk_bare_fn(fty)))
Ok(tcx.mk_fn_def(a_def_id, fty))
}

(&ty::TyFnPtr(a_fty), &ty::TyFnPtr(b_fty)) =>
{
let fty = try!(relation.relate(a_fty, b_fty));
Ok(tcx.mk_fn_ptr(fty))
}

(&ty::TyProjection(ref a_data), &ty::TyProjection(ref b_data)) =>
Expand Down
10 changes: 7 additions & 3 deletions src/librustc/middle/ty/structural_impls.rs
Expand Up @@ -282,9 +282,13 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
}
ty::TyTrait(ref trait_ty) => ty::TyTrait(trait_ty.fold_with(folder)),
ty::TyTuple(ref ts) => ty::TyTuple(ts.fold_with(folder)),
ty::TyBareFn(opt_def_id, ref f) => {
ty::TyFnDef(def_id, ref f) => {
let bfn = f.fold_with(folder);
ty::TyBareFn(opt_def_id, folder.tcx().mk_bare_fn(bfn))
ty::TyFnDef(def_id, folder.tcx().mk_bare_fn(bfn))
}
ty::TyFnPtr(ref f) => {
let bfn = f.fold_with(folder);
ty::TyFnPtr(folder.tcx().mk_bare_fn(bfn))
}
ty::TyRef(r, ref tm) => {
let r = r.fold_with(folder);
Expand Down Expand Up @@ -318,7 +322,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyEnum(_tid, ref substs) => substs.visit_with(visitor),
ty::TyTrait(ref trait_ty) => trait_ty.visit_with(visitor),
ty::TyTuple(ref ts) => ts.visit_with(visitor),
ty::TyBareFn(_opt_def_id, ref f) => f.visit_with(visitor),
ty::TyFnDef(_, ref f) | ty::TyFnPtr(ref f) => f.visit_with(visitor),
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
ty::TyStruct(_did, ref substs) => substs.visit_with(visitor),
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
Expand Down
43 changes: 16 additions & 27 deletions src/librustc/middle/ty/sty.rs
Expand Up @@ -127,14 +127,16 @@ pub enum TypeVariants<'tcx> {
/// `&a mut T` or `&'a T`.
TyRef(&'tcx Region, TypeAndMut<'tcx>),

/// If the def-id is Some(_), then this is the type of a specific
/// fn item. Otherwise, if None(_), it is a fn pointer type.
///
/// FIXME: Conflating function pointers and the type of a
/// function is probably a terrible idea; a function pointer is a
/// value with a specific type, but a function can be polymorphic
/// or dynamically dispatched.
TyBareFn(Option<DefId>, &'tcx BareFnTy<'tcx>),
/// The anonymous type of a function declaration/definition. Each
/// function has a unique type.
/// FIXME: Does this need to include substitutions?
/// `g::<i32>` and `g::<u32>` should have different types.
TyFnDef(DefId, &'tcx BareFnTy<'tcx>),

/// A pointer to a function. Written as `fn() -> i32`.
/// FIXME: This is currently also used to represent the callee of a method;
/// see ty::MethodCallee etc.
TyFnPtr(&'tcx BareFnTy<'tcx>),

/// A trait, defined with `trait`.
TyTrait(Box<TraitTy<'tcx>>),
Expand Down Expand Up @@ -1029,7 +1031,7 @@ impl<'tcx> TyS<'tcx> {
match self.sty {
TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) |
TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) |
TyBareFn(..) | TyRawPtr(_) => true,
TyFnDef(..) | TyFnPtr(_) | TyRawPtr(_) => true,
_ => false
}
}
Expand Down Expand Up @@ -1080,20 +1082,6 @@ impl<'tcx> TyS<'tcx> {
}
}

pub fn is_bare_fn(&self) -> bool {
match self.sty {
TyBareFn(..) => true,
_ => false
}
}

pub fn is_bare_fn_item(&self) -> bool {
match self.sty {
TyBareFn(Some(_), _) => true,
_ => false
}
}

pub fn is_fp(&self) -> bool {
match self.sty {
TyInfer(FloatVar(_)) | TyFloat(_) => true,
Expand Down Expand Up @@ -1154,15 +1142,15 @@ impl<'tcx> TyS<'tcx> {

pub fn fn_sig(&self) -> &'tcx PolyFnSig<'tcx> {
match self.sty {
TyBareFn(_, ref f) => &f.sig,
TyFnDef(_, ref f) | TyFnPtr(ref f) => &f.sig,
_ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self)
}
}

/// Returns the ABI of the given function.
pub fn fn_abi(&self) -> abi::Abi {
match self.sty {
TyBareFn(_, ref f) => f.abi,
TyFnDef(_, ref f) | TyFnPtr(ref f) => f.abi,
_ => panic!("Ty::fn_abi() called on non-fn type"),
}
}
Expand All @@ -1178,7 +1166,7 @@ impl<'tcx> TyS<'tcx> {

pub fn is_fn(&self) -> bool {
match self.sty {
TyBareFn(..) => true,
TyFnDef(..) | TyFnPtr(_) => true,
_ => false
}
}
Expand Down Expand Up @@ -1224,7 +1212,8 @@ impl<'tcx> TyS<'tcx> {
TyProjection(ref data) => {
data.trait_ref.substs.regions().as_slice().to_vec()
}
TyBareFn(..) |
TyFnDef(..) |
TyFnPtr(_) |
TyBool |
TyChar |
TyInt(_) |
Expand Down

0 comments on commit b423a0f

Please sign in to comment.