Skip to content

Commit 15a5f04

Browse files
committed
---
yaml --- r: 228651 b: refs/heads/try c: 4e67f9c h: refs/heads/master i: 228649: 78670e7 228647: b411d79 v: v3
1 parent 0cd203d commit 15a5f04

File tree

27 files changed

+278
-579
lines changed

27 files changed

+278
-579
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: c9ef1a5c19b8f9a254b0fb0b79a3bebf0722a9ce
4+
refs/heads/try: 4e67f9c611e31691aa1be1f2b1e09dc523fa7056
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc/middle/resolve_lifetime.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
109109

110110
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
111111
fn visit_item(&mut self, item: &ast::Item) {
112-
// Items save/restore the set of labels. This way inner items
112+
// Items save/restore the set of labels. This way innner items
113113
// can freely reuse names, be they loop labels or lifetimes.
114114
let saved = replace(&mut self.labels_in_fn, vec![]);
115115

@@ -151,29 +151,6 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
151151
replace(&mut self.labels_in_fn, saved);
152152
}
153153

154-
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
155-
// Items save/restore the set of labels. This way inner items
156-
// can freely reuse names, be they loop labels or lifetimes.
157-
let saved = replace(&mut self.labels_in_fn, vec![]);
158-
159-
// Items always introduce a new root scope
160-
self.with(RootScope, |_, this| {
161-
match item.node {
162-
ast::ForeignItemFn(_, ref generics) => {
163-
this.visit_early_late(subst::FnSpace, generics, |this| {
164-
visit::walk_foreign_item(this, item);
165-
})
166-
}
167-
ast::ForeignItemStatic(..) => {
168-
visit::walk_foreign_item(this, item);
169-
}
170-
}
171-
});
172-
173-
// Done traversing the item; restore saved set of labels.
174-
replace(&mut self.labels_in_fn, saved);
175-
}
176-
177154
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
178155
b: &'v ast::Block, s: Span, _: ast::NodeId) {
179156
match fk {

branches/try/src/librustc/middle/ty.rs

Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3967,6 +3967,7 @@ 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,
39703971
InteriorUnsafe = 0b0000_0000__0000_0000__0010,
39713972
InteriorParam = 0b0000_0000__0000_0000__0100,
39723973
// InteriorAll = 0b00000000__00000000__1111,
@@ -3976,9 +3977,18 @@ def_type_content_sets! {
39763977
OwnsDtor = 0b0000_0000__0000_0010__0000,
39773978
OwnsAll = 0b0000_0000__1111_1111__0000,
39783979

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+
39793986
// Things that mean drop glue is necessary
39803987
NeedsDrop = 0b0000_0000__0000_0111__0000,
39813988

3989+
// Things that prevent values from being considered sized
3990+
Nonsized = 0b0000_0000__0000_0000__0001,
3991+
39823992
// All bits
39833993
All = 0b1111_1111__1111_1111__1111
39843994
}
@@ -3997,6 +4007,10 @@ impl TypeContents {
39974007
self.intersects(TC::OwnsOwned)
39984008
}
39994009

4010+
pub fn is_sized(&self, _: &ctxt) -> bool {
4011+
!self.intersects(TC::Nonsized)
4012+
}
4013+
40004014
pub fn interior_param(&self) -> bool {
40014015
self.intersects(TC::InteriorParam)
40024016
}
@@ -4005,13 +4019,29 @@ impl TypeContents {
40054019
self.intersects(TC::InteriorUnsafe)
40064020
}
40074021

4022+
pub fn interior_unsized(&self) -> bool {
4023+
self.intersects(TC::InteriorUnsized)
4024+
}
4025+
40084026
pub fn needs_drop(&self, _: &ctxt) -> bool {
40094027
self.intersects(TC::NeedsDrop)
40104028
}
40114029

40124030
/// Includes only those bits that still apply when indirected through a `Box` pointer
40134031
pub fn owned_pointer(&self) -> TypeContents {
4014-
TC::OwnsOwned | (*self & TC::OwnsAll)
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
40154045
}
40164046

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

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

41124142
TyBox(typ) => {
4113-
tc_ty(cx, typ, cache).owned_pointer()
4143+
TC::ReachesFfiUnsafe | tc_ty(cx, typ, cache).owned_pointer()
41144144
}
41154145

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

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

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

41284159
TyArray(ty, _) => {
41294160
tc_ty(cx, ty, cache)
41304161
}
41314162

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

41374168
TyStruct(did, substs) => {
41384169
let flds = cx.struct_fields(did, substs);
41394170
let mut res =
41404171
TypeContents::union(&flds[..],
4141-
|f| tc_ty(cx, f.mt.ty, cache));
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+
}
41424177

41434178
if cx.has_dtor(did) {
41444179
res = res | TC::OwnsDtor;
@@ -4147,6 +4182,7 @@ impl<'tcx> TyS<'tcx> {
41474182
}
41484183

41494184
TyClosure(did, substs) => {
4185+
// FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
41504186
let param_env = cx.empty_parameter_environment();
41514187
let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false);
41524188
let upvars = infcx.closure_upvars(did, substs).unwrap();
@@ -4172,6 +4208,44 @@ impl<'tcx> TyS<'tcx> {
41724208
res = res | TC::OwnsDtor;
41734209
}
41744210

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+
41754249
apply_lang_items(cx, did, res)
41764250
}
41774251

@@ -4190,6 +4264,14 @@ impl<'tcx> TyS<'tcx> {
41904264
result
41914265
}
41924266

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+
41934275
fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
41944276
-> TypeContents {
41954277
if Some(did) == cx.lang_items.unsafe_cell_type() {
@@ -4198,6 +4280,32 @@ impl<'tcx> TyS<'tcx> {
41984280
tc
41994281
}
42004282
}
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+
}
42014309
}
42024310

42034311
fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
@@ -4291,6 +4399,10 @@ impl<'tcx> TyS<'tcx> {
42914399
result
42924400
}
42934401

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

0 commit comments

Comments
 (0)