Skip to content

Commit 9ad3b94

Browse files
committed
rustc: replace TypeContents::needs_drop with Ty::may_drop.
1 parent 6563374 commit 9ad3b94

File tree

4 files changed

+87
-154
lines changed

4 files changed

+87
-154
lines changed

src/librustc/ty/contents.rs

-139
This file was deleted.

src/librustc/ty/context.rs

-4
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,6 @@ pub struct GlobalCtxt<'tcx> {
436436
// Internal cache for metadata decoding. No need to track deps on this.
437437
pub rcache: RefCell<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
438438

439-
// Cache for the type-contents routine. FIXME -- track deps?
440-
pub tc_cache: RefCell<FxHashMap<Ty<'tcx>, ty::contents::TypeContents>>,
441-
442439
// FIXME dep tracking -- should be harmless enough
443440
pub normalized_cache: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
444441

@@ -708,7 +705,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
708705
freevars: RefCell::new(resolutions.freevars),
709706
maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
710707
rcache: RefCell::new(FxHashMap()),
711-
tc_cache: RefCell::new(FxHashMap()),
712708
normalized_cache: RefCell::new(FxHashMap()),
713709
inhabitedness_cache: RefCell::new(FxHashMap()),
714710
lang_items: lang_items,

src/librustc/ty/mod.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ pub use self::sty::InferTy::*;
7171
pub use self::sty::Region::*;
7272
pub use self::sty::TypeVariants::*;
7373

74-
pub use self::contents::TypeContents;
7574
pub use self::context::{TyCtxt, GlobalArenas, tls};
7675
pub use self::context::{Lift, TypeckTables};
7776

@@ -99,7 +98,6 @@ pub mod walk;
9998
pub mod wf;
10099
pub mod util;
101100

102-
mod contents;
103101
mod context;
104102
mod flags;
105103
mod instance;
@@ -427,6 +425,8 @@ bitflags! {
427425
const MOVES_BY_DEFAULT = 1 << 19,
428426
const FREEZENESS_CACHED = 1 << 20,
429427
const IS_FREEZE = 1 << 21,
428+
const MAY_DROP_CACHED = 1 << 22,
429+
const MAY_DROP = 1 << 23,
430430
}
431431
}
432432

@@ -2400,19 +2400,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
24002400
if implements_copy { return false; }
24012401

24022402
// ... (issue #22536 continued) but as an optimization, still use
2403-
// prior logic of asking if the `needs_drop` bit is set; we need
2404-
// not zero non-Copy types if they have no destructor.
2403+
// prior logic of asking for the structural `may_drop`.
24052404

2406-
// FIXME(#22815): Note that calling `ty::type_contents` is a
2407-
// conservative heuristic; it may report that `needs_drop` is set
2405+
// FIXME(#22815): Note that calling `ty::may_drop` is a
2406+
// conservative heuristic; it may report `true` ("may drop")
24082407
// when actual type does not actually have a destructor associated
24092408
// with it. But since `ty` absolutely did not have the `Copy`
24102409
// bound attached (see above), it is sound to treat it as having a
2411-
// destructor (e.g. zero its memory on move).
2410+
// destructor.
24122411

2413-
let contents = ty.type_contents(tcx);
2414-
debug!("type_needs_drop ty={:?} contents={:?}", ty, contents.bits());
2415-
contents.needs_drop(tcx)
2412+
let may_drop = ty.may_drop(tcx);
2413+
debug!("type_needs_drop ty={:?} may_drop={:?}", ty, may_drop);
2414+
may_drop
24162415
}
24172416

24182417
/// Get the attributes of a definition.

src/librustc/ty/util.rs

+78-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use ty::fold::TypeVisitor;
2121
use ty::layout::{Layout, LayoutError};
2222
use ty::TypeVariants::*;
2323
use util::common::ErrorReported;
24-
use util::nodemap::FxHashMap;
24+
use util::nodemap::{FxHashMap, FxHashSet};
2525
use middle::lang_items;
2626

2727
use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
@@ -699,6 +699,83 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
699699
result
700700
}
701701

702+
#[inline]
703+
pub fn may_drop(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
704+
if self.flags.get().intersects(TypeFlags::MAY_DROP_CACHED) {
705+
return self.flags.get().intersects(TypeFlags::MAY_DROP);
706+
}
707+
708+
self.may_drop_inner(tcx, &mut FxHashSet())
709+
}
710+
711+
fn may_drop_inner(&'tcx self,
712+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
713+
visited: &mut FxHashSet<Ty<'tcx>>)
714+
-> bool {
715+
if self.flags.get().intersects(TypeFlags::MAY_DROP_CACHED) {
716+
return self.flags.get().intersects(TypeFlags::MAY_DROP);
717+
}
718+
719+
// This should be reported as an error by `check_representable`.
720+
//
721+
// Consider the type as not needing drop in the meanwhile to avoid
722+
// further errors.
723+
if visited.replace(self).is_some() {
724+
return false;
725+
}
726+
727+
assert!(!self.needs_infer());
728+
729+
let result = match self.sty {
730+
// Fast-path for primitive types
731+
ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) |
732+
ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyNever |
733+
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
734+
ty::TyRawPtr(_) | ty::TyRef(..) | ty::TyStr => false,
735+
736+
// User destructors are the only way to have concrete drop types.
737+
ty::TyAdt(def, _) if def.has_dtor(tcx) => true,
738+
739+
// Can refer to a type which may drop.
740+
// FIXME(eddyb) check this against a ParameterEnvironment.
741+
ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) |
742+
ty::TyAnon(..) | ty::TyInfer(_) | ty::TyError => true,
743+
744+
// Structural recursion.
745+
ty::TyArray(ty, _) | ty::TySlice(ty) => {
746+
ty.may_drop_inner(tcx, visited)
747+
}
748+
749+
ty::TyClosure(def_id, ref substs) => {
750+
substs.upvar_tys(def_id, tcx)
751+
.any(|ty| ty.may_drop_inner(tcx, visited))
752+
}
753+
754+
ty::TyTuple(ref tys, _) => {
755+
tys.iter().any(|ty| ty.may_drop_inner(tcx, visited))
756+
}
757+
758+
// unions don't have destructors regardless of the child types
759+
ty::TyAdt(def, _) if def.is_union() => false,
760+
761+
ty::TyAdt(def, substs) => {
762+
def.variants.iter().any(|v| {
763+
v.fields.iter().any(|f| {
764+
f.ty(tcx, substs).may_drop_inner(tcx, visited)
765+
})
766+
})
767+
}
768+
};
769+
770+
self.flags.set(self.flags.get() | if result {
771+
TypeFlags::MAY_DROP_CACHED | TypeFlags::MAY_DROP
772+
} else {
773+
TypeFlags::MAY_DROP_CACHED
774+
});
775+
776+
result
777+
}
778+
702779
#[inline]
703780
pub fn layout<'lcx>(&'tcx self, infcx: &InferCtxt<'a, 'tcx, 'lcx>)
704781
-> Result<&'tcx Layout, LayoutError<'tcx>> {

0 commit comments

Comments
 (0)