Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Distinguish fn item types to allow reification from nothing to fn pointers. #31710

Merged
merged 19 commits into from
Mar 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b423a0f
Split TyBareFn into TyFnDef and TyFnPtr.
eefriedman Jun 13, 2015
ffa0860
Track fn type and lifetime parameters in TyFnDef.
eddyb Feb 16, 2016
e4e1242
Print fn type parameters for TyFnDef.
eddyb Feb 16, 2016
0c01f6e
trans: Move type_of_fn_from_ty callers to type_of.
eddyb Feb 17, 2016
c284099
trans: Remove unused ref_id from monomorphic_fn.
eddyb Feb 17, 2016
8f07f8a
trans: Reify functions & methods to fn ptrs only where necessary.
eddyb Mar 6, 2016
847f007
typeck: Introduce reification for fn ptr casts.
eddyb Feb 18, 2016
644d639
typeck: Use TyFnDef for methods.
eddyb Feb 18, 2016
61a77b3
tests: Avoid transmuting from fn item types.
eddyb Feb 18, 2016
1b7fb17
Test that function types are actually zero-sized.
eddyb Feb 21, 2016
2b1bd80
infer: Remove redundant commit_if_ok calls.
eddyb Feb 21, 2016
871a1e1
typeck: rename mk_assignty to coercion::try.
eddyb Feb 21, 2016
dc37664
infer: Take the origin in report_mismatched_types.
eddyb Feb 21, 2016
dbab236
typeck: Remove Coerce::unpack_actual_value.
eddyb Feb 21, 2016
3ff4c34
typeck: don't wastefully clone expressions for cast checks.
eddyb Feb 21, 2016
ad91f19
typeck: Support multiple expressions getting coerced at the same type.
eddyb Feb 22, 2016
d2c6bef
typeck: Remove the redundant "unifier" from check_expr_with_unifier.
eddyb Feb 22, 2016
eb926dd
typeck: Unify if-else blocks, match arms and array elements by coerci…
eddyb Mar 6, 2016
3855fa9
trans: Keep transmutes from fn item types working, but lint them.
eddyb Mar 9, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ declare_lint! {
"uses of #[derive] with raw pointers are rarely correct"
}

declare_lint! {
pub TRANSMUTE_FROM_FN_ITEM_TYPES,
Warn,
"transmute from function item type to pointer-sized type erroneously allowed"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
Expand Down Expand Up @@ -177,7 +183,8 @@ impl LintPass for HardwiredLints {
INVALID_TYPE_PARAM_DEFAULT,
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
CONST_ERR,
RAW_POINTER_DERIVE
RAW_POINTER_DERIVE,
TRANSMUTE_FROM_FN_ITEM_TYPES
)
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,9 @@ pub fn check_crate(tcx: &TyCtxt, access_levels: &AccessLevels) {
}

*tcx.node_lint_levels.borrow_mut() = cx.node_levels.into_inner();

// Put the lint store back in the session.
mem::replace(&mut *tcx.sess.lint_store.borrow_mut(), cx.lints);
}

pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
14 changes: 7 additions & 7 deletions src/librustc/middle/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
-> UnitResult<'tcx>
{
debug!("mk_eqty({:?} <: {:?})", a, b);
cx.commit_if_ok(|_| cx.eq_types(a_is_expected, origin, a, b))
cx.eq_types(a_is_expected, origin, a, b)
}

pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
Expand All @@ -466,7 +466,7 @@ pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
{
debug!("mk_eq_trait_refs({:?} <: {:?})",
a, b);
cx.commit_if_ok(|_| cx.eq_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
cx.eq_trait_refs(a_is_expected, origin, a, b)
}

pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
Expand All @@ -478,7 +478,7 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
{
debug!("mk_sub_poly_trait_refs({:?} <: {:?})",
a, b);
cx.commit_if_ok(|_| cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
cx.sub_poly_trait_refs(a_is_expected, origin, a, b)
}

fn expected_found<T>(a_is_expected: bool,
Expand Down Expand Up @@ -1351,18 +1351,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

pub fn report_mismatched_types(&self,
span: Span,
origin: TypeOrigin,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
err: &TypeError<'tcx>) {
err: TypeError<'tcx>) {
let trace = TypeTrace {
origin: TypeOrigin::Misc(span),
origin: origin,
values: Types(ExpectedFound {
expected: expected,
found: actual
})
};
self.report_and_explain_type_error(trace, err);
self.report_and_explain_type_error(trace, &err);
}

pub fn report_conflicting_default_types(&self,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
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
4 changes: 2 additions & 2 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ impl<'tcx> Substs<'tcx> {
Substs { types: types, regions: regions }
}

pub fn with_method_from(self,
pub fn with_method_from(&self,
meth_substs: &Substs<'tcx>)
-> Substs<'tcx>
{
let Substs { types, regions } = self;
let Substs { types, regions } = self.clone();
let types = types.with_slice(FnSpace, meth_substs.types.get_slice(FnSpace));
let regions = regions.map(|r| {
r.with_slice(FnSpace, meth_substs.regions().get_slice(FnSpace))
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/traits/coherence.rs
Original file line number Diff line number Diff line change
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
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ pub enum Vtable<'tcx, N> {
#[derive(Clone, PartialEq, Eq)]
pub struct VtableImplData<'tcx, N> {
pub impl_def_id: DefId,
pub substs: subst::Substs<'tcx>,
pub substs: &'tcx subst::Substs<'tcx>,
pub nested: Vec<N>
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ fn confirm_impl_candidate<'cx,'tcx>(
for impl_item in &selcx.tcx().impl_items.borrow()[&impl_vtable.impl_def_id] {
if let ty::TypeTraitItem(ref assoc_ty) = impl_or_trait_items_map[&impl_item.def_id()] {
if assoc_ty.name == obligation.predicate.item_name {
return (assoc_ty.ty.unwrap().subst(selcx.tcx(), &impl_vtable.substs),
return (assoc_ty.ty.unwrap().subst(selcx.tcx(), impl_vtable.substs),
impl_vtable.nested);
}
}
Expand Down
19 changes: 15 additions & 4 deletions src/librustc/middle/traits/select.rs
Original file line number Diff line number Diff line change
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 Expand Up @@ -2294,7 +2305,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
impl_obligations.append(&mut substs.obligations);

VtableImplData { impl_def_id: impl_def_id,
substs: substs.value,
substs: self.tcx().mk_substs(substs.value),
nested: impl_obligations }
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,10 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx

impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
fn super_fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let substs = self.substs.fold_with(folder);
traits::VtableImplData {
impl_def_id: self.impl_def_id,
substs: self.substs.fold_with(folder),
substs: folder.tcx().mk_substs(substs),
nested: self.nested.fold_with(folder),
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/ty/adjustment.rs
Original file line number Diff line number Diff line change
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
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ 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),
ty::TyFnPtr(..) => Some(CastTy::FnPtr),
_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/contents.rs
Original file line number Diff line number Diff line change
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
38 changes: 12 additions & 26 deletions src/librustc/middle/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ use std::borrow::Borrow;
use std::cell::{Cell, RefCell, Ref};
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
use syntax::parse::token::special_idents;
Expand Down Expand Up @@ -734,8 +733,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 +791,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 +944,14 @@ 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_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 {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: input_args,
output: ty::FnConverging(output),
variadic: false
})
}))
pub fn mk_fn_def(&self, def_id: DefId,
substs: &'tcx Substs<'tcx>,
fty: BareFnTy<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyFnDef(def_id, substs, 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_trait(&self,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/ty/error.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
7 changes: 6 additions & 1 deletion src/librustc/middle/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,12 @@ impl FlagComputation {
self.add_tys(&ts[..]);
}

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

&ty::TyFnPtr(ref f) => {
self.add_fn_sig(&f.sig);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/ty/outlives.rs
Original file line number Diff line number Diff line change
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
Loading