use memoized pattern for SizedConstraint

I cannot figure out how to write a test for this, but I observed
incorrect edges as a result of not using memoized pattern here
(e.g., LateLintCheck -> SizedConstraint).
This commit is contained in:
Niko Matsakis 2016-08-02 19:12:02 -04:00
parent b13d5041f6
commit 54595ecb60
2 changed files with 13 additions and 6 deletions

View File

@ -52,8 +52,10 @@ impl<'tcx, 'lt> TyIVar<'tcx, 'lt> {
self.untracked_get()
}
/// Reads the ivar without registered a dep-graph read. Use with
/// caution.
#[inline]
fn untracked_get(&self) -> Option<Ty<'tcx>> {
pub fn untracked_get(&self) -> Option<Ty<'tcx>> {
match self.0.get() {
None => None,
// valid because of invariant (A)

View File

@ -1757,8 +1757,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
/// Due to normalization being eager, this applies even if
/// the associated type is behind a pointer, e.g. issue #31299.
pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
let dep_node = DepNode::SizedConstraint(self.did);
match self.sized_constraint.get(dep_node) {
match self.sized_constraint.get(DepNode::SizedConstraint(self.did)) {
None => {
let global_tcx = tcx.global_tcx();
let this = global_tcx.lookup_adt_def_master(self.did);
@ -1786,12 +1785,18 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
/// such.
/// - a TyError, if a type contained itself. The representability
/// check should catch this case.
fn calculate_sized_constraint_inner(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn calculate_sized_constraint_inner(&'tcx self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
stack: &mut Vec<AdtDefMaster<'tcx>>)
{
let dep_node = || DepNode::SizedConstraint(self.did);
if self.sized_constraint.get(dep_node()).is_some() {
// Follow the memoization pattern: push the computation of
// DepNode::SizedConstraint as our current task.
let _task = tcx.dep_graph.in_task(dep_node());
if self.sized_constraint.untracked_get().is_some() {
// ---------------
// can skip the dep-graph read since we just pushed the task
return;
}