Skip to content

Commit 68e0d13

Browse files
committed
Auto merge of #26583 - eefriedman:lint-ffi, r=nrc
Makes the lint a bit more accurate, and improves the quality of the diagnostic messages by explicitly returning an error message.
2 parents 69ca012 + 6fa17b4 commit 68e0d13

File tree

14 files changed

+345
-177
lines changed

14 files changed

+345
-177
lines changed

src/librustc/middle/ty.rs

+12-124
Original file line numberDiff line numberDiff line change
@@ -3967,7 +3967,6 @@ def_type_content_sets! {
39673967
None = 0b0000_0000__0000_0000__0000,
39683968

39693969
// Things that are interior to the value (first nibble):
3970-
InteriorUnsized = 0b0000_0000__0000_0000__0001,
39713970
InteriorUnsafe = 0b0000_0000__0000_0000__0010,
39723971
InteriorParam = 0b0000_0000__0000_0000__0100,
39733972
// InteriorAll = 0b00000000__00000000__1111,
@@ -3977,18 +3976,9 @@ def_type_content_sets! {
39773976
OwnsDtor = 0b0000_0000__0000_0010__0000,
39783977
OwnsAll = 0b0000_0000__1111_1111__0000,
39793978

3980-
// Things that are reachable by the value in any way (fourth nibble):
3981-
ReachesBorrowed = 0b0000_0010__0000_0000__0000,
3982-
ReachesMutable = 0b0000_1000__0000_0000__0000,
3983-
ReachesFfiUnsafe = 0b0010_0000__0000_0000__0000,
3984-
ReachesAll = 0b0011_1111__0000_0000__0000,
3985-
39863979
// Things that mean drop glue is necessary
39873980
NeedsDrop = 0b0000_0000__0000_0111__0000,
39883981

3989-
// Things that prevent values from being considered sized
3990-
Nonsized = 0b0000_0000__0000_0000__0001,
3991-
39923982
// All bits
39933983
All = 0b1111_1111__1111_1111__1111
39943984
}
@@ -4007,10 +3997,6 @@ impl TypeContents {
40073997
self.intersects(TC::OwnsOwned)
40083998
}
40093999

4010-
pub fn is_sized(&self, _: &ctxt) -> bool {
4011-
!self.intersects(TC::Nonsized)
4012-
}
4013-
40144000
pub fn interior_param(&self) -> bool {
40154001
self.intersects(TC::InteriorParam)
40164002
}
@@ -4019,29 +4005,13 @@ impl TypeContents {
40194005
self.intersects(TC::InteriorUnsafe)
40204006
}
40214007

4022-
pub fn interior_unsized(&self) -> bool {
4023-
self.intersects(TC::InteriorUnsized)
4024-
}
4025-
40264008
pub fn needs_drop(&self, _: &ctxt) -> bool {
40274009
self.intersects(TC::NeedsDrop)
40284010
}
40294011

40304012
/// Includes only those bits that still apply when indirected through a `Box` pointer
40314013
pub fn owned_pointer(&self) -> TypeContents {
4032-
TC::OwnsOwned | (
4033-
*self & (TC::OwnsAll | TC::ReachesAll))
4034-
}
4035-
4036-
/// Includes only those bits that still apply when indirected through a reference (`&`)
4037-
pub fn reference(&self, bits: TypeContents) -> TypeContents {
4038-
bits | (
4039-
*self & TC::ReachesAll)
4040-
}
4041-
4042-
/// Includes only those bits that still apply when indirected through a raw pointer (`*`)
4043-
pub fn unsafe_pointer(&self) -> TypeContents {
4044-
*self & TC::ReachesAll
4014+
TC::OwnsOwned | (*self & TC::OwnsAll)
40454015
}
40464016

40474017
pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
@@ -4129,7 +4099,7 @@ impl<'tcx> TyS<'tcx> {
41294099
let result = match ty.sty {
41304100
// usize and isize are ffi-unsafe
41314101
TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
4132-
TC::ReachesFfiUnsafe
4102+
TC::None
41334103
}
41344104

41354105
// Scalar and unique types are sendable, and durable
@@ -4140,40 +4110,35 @@ impl<'tcx> TyS<'tcx> {
41404110
}
41414111

41424112
TyBox(typ) => {
4143-
TC::ReachesFfiUnsafe | tc_ty(cx, typ, cache).owned_pointer()
4113+
tc_ty(cx, typ, cache).owned_pointer()
41444114
}
41454115

4146-
TyTrait(box TraitTy { ref bounds, .. }) => {
4147-
object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
4116+
TyTrait(_) => {
4117+
TC::All - TC::InteriorParam
41484118
}
41494119

4150-
TyRawPtr(ref mt) => {
4151-
tc_ty(cx, mt.ty, cache).unsafe_pointer()
4120+
TyRawPtr(_) => {
4121+
TC::None
41524122
}
41534123

4154-
TyRef(r, ref mt) => {
4155-
tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)) |
4156-
TC::ReachesFfiUnsafe
4124+
TyRef(_, _) => {
4125+
TC::None
41574126
}
41584127

41594128
TyArray(ty, _) => {
41604129
tc_ty(cx, ty, cache)
41614130
}
41624131

41634132
TySlice(ty) => {
4164-
tc_ty(cx, ty, cache) | TC::Nonsized
4133+
tc_ty(cx, ty, cache)
41654134
}
4166-
TyStr => TC::Nonsized,
4135+
TyStr => TC::None,
41674136

41684137
TyStruct(did, substs) => {
41694138
let flds = cx.struct_fields(did, substs);
41704139
let mut res =
41714140
TypeContents::union(&flds[..],
4172-
|f| tc_mt(cx, f.mt, cache));
4173-
4174-
if !cx.lookup_repr_hints(did).contains(&attr::ReprExtern) {
4175-
res = res | TC::ReachesFfiUnsafe;
4176-
}
4141+
|f| tc_ty(cx, f.mt.ty, cache));
41774142

41784143
if cx.has_dtor(did) {
41794144
res = res | TC::OwnsDtor;
@@ -4182,7 +4147,6 @@ impl<'tcx> TyS<'tcx> {
41824147
}
41834148

41844149
TyClosure(did, substs) => {
4185-
// FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
41864150
let param_env = cx.empty_parameter_environment();
41874151
let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false);
41884152
let upvars = infcx.closure_upvars(did, substs).unwrap();
@@ -4208,44 +4172,6 @@ impl<'tcx> TyS<'tcx> {
42084172
res = res | TC::OwnsDtor;
42094173
}
42104174

4211-
if !variants.is_empty() {
4212-
let repr_hints = cx.lookup_repr_hints(did);
4213-
if repr_hints.len() > 1 {
4214-
// this is an error later on, but this type isn't safe
4215-
res = res | TC::ReachesFfiUnsafe;
4216-
}
4217-
4218-
match repr_hints.get(0) {
4219-
Some(h) => if !h.is_ffi_safe() {
4220-
res = res | TC::ReachesFfiUnsafe;
4221-
},
4222-
// ReprAny
4223-
None => {
4224-
res = res | TC::ReachesFfiUnsafe;
4225-
4226-
// We allow ReprAny enums if they are eligible for
4227-
// the nullable pointer optimization and the
4228-
// contained type is an `extern fn`
4229-
4230-
if variants.len() == 2 {
4231-
let mut data_idx = 0;
4232-
4233-
if variants[0].args.is_empty() {
4234-
data_idx = 1;
4235-
}
4236-
4237-
if variants[data_idx].args.len() == 1 {
4238-
match variants[data_idx].args[0].sty {
4239-
TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
4240-
_ => { }
4241-
}
4242-
}
4243-
}
4244-
}
4245-
}
4246-
}
4247-
4248-
42494175
apply_lang_items(cx, did, res)
42504176
}
42514177

@@ -4264,14 +4190,6 @@ impl<'tcx> TyS<'tcx> {
42644190
result
42654191
}
42664192

4267-
fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
4268-
mt: TypeAndMut<'tcx>,
4269-
cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
4270-
{
4271-
let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
4272-
mc | tc_ty(cx, mt.ty, cache)
4273-
}
4274-
42754193
fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
42764194
-> TypeContents {
42774195
if Some(did) == cx.lang_items.unsafe_cell_type() {
@@ -4280,32 +4198,6 @@ impl<'tcx> TyS<'tcx> {
42804198
tc
42814199
}
42824200
}
4283-
4284-
/// Type contents due to containing a reference with
4285-
/// the region `region` and borrow kind `bk`.
4286-
fn borrowed_contents(region: ty::Region,
4287-
mutbl: ast::Mutability)
4288-
-> TypeContents {
4289-
let b = match mutbl {
4290-
ast::MutMutable => TC::ReachesMutable,
4291-
ast::MutImmutable => TC::None,
4292-
};
4293-
b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
4294-
}
4295-
4296-
fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
4297-
// These are the type contents of the (opaque) interior. We
4298-
// make no assumptions (other than that it cannot have an
4299-
// in-scope type parameter within, which makes no sense).
4300-
let mut tc = TC::All - TC::InteriorParam;
4301-
for bound in &bounds.builtin_bounds {
4302-
tc = tc - match bound {
4303-
BoundSync | BoundSend | BoundCopy => TC::None,
4304-
BoundSized => TC::Nonsized,
4305-
};
4306-
}
4307-
return tc;
4308-
}
43094201
}
43104202

43114203
fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
@@ -4399,10 +4291,6 @@ impl<'tcx> TyS<'tcx> {
43994291
result
44004292
}
44014293

4402-
pub fn is_ffi_safe(&'tcx self, cx: &ctxt<'tcx>) -> bool {
4403-
!self.type_contents(cx).intersects(TC::ReachesFfiUnsafe)
4404-
}
4405-
44064294
// True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
44074295
pub fn is_instantiable(&'tcx self, cx: &ctxt<'tcx>) -> bool {
44084296
fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,

0 commit comments

Comments
 (0)