Skip to content

Commit bcda58f

Browse files
committed
Auto merge of #31710 - eddyb:reify, r=nikomatsakis
Distinguish fn item types to allow reification from nothing to fn pointers. The first commit is a rebase of #26284, except for files that have moved since. This is a [breaking-change], due to: * each FFI function has a distinct type, like all other functions currently do * all generic parameters on functions are recorded in their item types, e.g.: `size_of::<u8>` & `size_of::<i8>`'s types differ despite their identical signature. * function items are zero-sized, which will stop transmutes from working on them The first two cases are handled in most cases with the new coerce-unify logic, which will combine incompatible function item types into function pointers, at the outer-most level of if-else chains, match arms and array literals. The last case is specially handled during type-checking such that transmutes from a function item type to a pointer or integer type will continue to work for another release cycle, but are being linted against. To get rid of warnings and ensure your code will continue to compile, cast to a pointer before transmuting.
2 parents 0b9995b + 3855fa9 commit bcda58f

File tree

109 files changed

+2056
-2242
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+2056
-2242
lines changed

src/librustc/lint/builtin.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ declare_lint! {
148148
"uses of #[derive] with raw pointers are rarely correct"
149149
}
150150

151+
declare_lint! {
152+
pub TRANSMUTE_FROM_FN_ITEM_TYPES,
153+
Warn,
154+
"transmute from function item type to pointer-sized type erroneously allowed"
155+
}
156+
151157
/// Does nothing as a lint pass, but registers some `Lint`s
152158
/// which are used by other parts of the compiler.
153159
#[derive(Copy, Clone)]
@@ -177,7 +183,8 @@ impl LintPass for HardwiredLints {
177183
INVALID_TYPE_PARAM_DEFAULT,
178184
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
179185
CONST_ERR,
180-
RAW_POINTER_DERIVE
186+
RAW_POINTER_DERIVE,
187+
TRANSMUTE_FROM_FN_ITEM_TYPES
181188
)
182189
}
183190
}

src/librustc/lint/context.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,9 @@ pub fn check_crate(tcx: &TyCtxt, access_levels: &AccessLevels) {
12871287
}
12881288

12891289
*tcx.node_lint_levels.borrow_mut() = cx.node_levels.into_inner();
1290+
1291+
// Put the lint store back in the session.
1292+
mem::replace(&mut *tcx.sess.lint_store.borrow_mut(), cx.lints);
12901293
}
12911294

12921295
pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {

src/librustc/middle/effect.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ enum RootUnsafeContext {
4444

4545
fn type_is_unsafe_function(ty: Ty) -> bool {
4646
match ty.sty {
47-
ty::TyBareFn(_, ref f) => f.unsafety == hir::Unsafety::Unsafe,
47+
ty::TyFnDef(_, _, ref f) |
48+
ty::TyFnPtr(ref f) => f.unsafety == hir::Unsafety::Unsafe,
4849
_ => false,
4950
}
5051
}

src/librustc/middle/expr_use_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
556556
callee, callee_ty);
557557
let call_scope = self.tcx().region_maps.node_extent(call.id);
558558
match callee_ty.sty {
559-
ty::TyBareFn(..) => {
559+
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
560560
self.consume_expr(callee);
561561
}
562562
ty::TyError => { }

src/librustc/middle/infer/freshen.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
161161
ty::TySlice(..) |
162162
ty::TyRawPtr(..) |
163163
ty::TyRef(..) |
164-
ty::TyBareFn(..) |
164+
ty::TyFnDef(..) |
165+
ty::TyFnPtr(_) |
165166
ty::TyTrait(..) |
166167
ty::TyStruct(..) |
167168
ty::TyClosure(..) |

src/librustc/middle/infer/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
454454
-> UnitResult<'tcx>
455455
{
456456
debug!("mk_eqty({:?} <: {:?})", a, b);
457-
cx.commit_if_ok(|_| cx.eq_types(a_is_expected, origin, a, b))
457+
cx.eq_types(a_is_expected, origin, a, b)
458458
}
459459

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

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

484484
fn expected_found<T>(a_is_expected: bool,
@@ -1351,18 +1351,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13511351
}
13521352

13531353
pub fn report_mismatched_types(&self,
1354-
span: Span,
1354+
origin: TypeOrigin,
13551355
expected: Ty<'tcx>,
13561356
actual: Ty<'tcx>,
1357-
err: &TypeError<'tcx>) {
1357+
err: TypeError<'tcx>) {
13581358
let trace = TypeTrace {
1359-
origin: TypeOrigin::Misc(span),
1359+
origin: origin,
13601360
values: Types(ExpectedFound {
13611361
expected: expected,
13621362
found: actual
13631363
})
13641364
};
1365-
self.report_and_explain_type_error(trace, err);
1365+
self.report_and_explain_type_error(trace, &err);
13661366
}
13671367

13681368
pub fn report_conflicting_default_types(&self,

src/librustc/middle/intrinsicck.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use dep_graph::DepNode;
1212
use middle::def::Def;
1313
use middle::def_id::DefId;
1414
use middle::subst::{Subst, Substs, EnumeratedItems};
15-
use middle::ty::{TransmuteRestriction, TyCtxt, TyBareFn};
15+
use middle::ty::{TransmuteRestriction, TyCtxt};
1616
use middle::ty::{self, Ty, TypeFoldable};
1717

1818
use std::fmt;
@@ -53,7 +53,7 @@ struct IntrinsicCheckingVisitor<'a, 'tcx: 'a> {
5353
impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
5454
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
5555
let intrinsic = match self.tcx.lookup_item_type(def_id).ty.sty {
56-
ty::TyBareFn(_, ref bfty) => bfty.abi == RustIntrinsic,
56+
ty::TyFnDef(_, _, ref bfty) => bfty.abi == RustIntrinsic,
5757
_ => return false
5858
};
5959
intrinsic && self.tcx.item_name(def_id).as_str() == "transmute"
@@ -238,7 +238,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
238238
Def::Fn(did) if self.def_id_is_transmute(did) => {
239239
let typ = self.tcx.node_id_to_type(expr.id);
240240
match typ.sty {
241-
TyBareFn(_, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
241+
ty::TyFnDef(_, _, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
242242
if let ty::FnConverging(to) = bare_fn_ty.sig.0.output {
243243
let from = bare_fn_ty.sig.0.inputs[0];
244244
self.check_transmute(expr.span, from, to, expr.id);

src/librustc/middle/subst.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,11 @@ impl<'tcx> Substs<'tcx> {
148148
Substs { types: types, regions: regions }
149149
}
150150

151-
pub fn with_method_from(self,
151+
pub fn with_method_from(&self,
152152
meth_substs: &Substs<'tcx>)
153153
-> Substs<'tcx>
154154
{
155-
let Substs { types, regions } = self;
155+
let Substs { types, regions } = self.clone();
156156
let types = types.with_slice(FnSpace, meth_substs.types.get_slice(FnSpace));
157157
let regions = regions.map(|r| {
158158
r.with_slice(FnSpace, meth_substs.regions().get_slice(FnSpace))

src/librustc/middle/traits/coherence.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ fn ty_is_local_constructor<'tcx>(tcx: &TyCtxt<'tcx>,
301301
ty::TyUint(..) |
302302
ty::TyFloat(..) |
303303
ty::TyStr |
304-
ty::TyBareFn(..) |
304+
ty::TyFnDef(..) |
305+
ty::TyFnPtr(_) |
305306
ty::TyArray(..) |
306307
ty::TySlice(..) |
307308
ty::TyRawPtr(..) |

src/librustc/middle/traits/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ pub enum Vtable<'tcx, N> {
278278
#[derive(Clone, PartialEq, Eq)]
279279
pub struct VtableImplData<'tcx, N> {
280280
pub impl_def_id: DefId,
281-
pub substs: subst::Substs<'tcx>,
281+
pub substs: &'tcx subst::Substs<'tcx>,
282282
pub nested: Vec<N>
283283
}
284284

0 commit comments

Comments
 (0)