From ddae395583ccad7cfacf1ee8e7bfeb5fca200c90 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 19 Jul 2021 14:05:13 +0200 Subject: [PATCH] ignore const substs in `implicit_infer` --- compiler/rustc_middle/src/ty/walk.rs | 31 +++++++++++++------ .../src/outlives/implicit_infer.rs | 7 ++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 3cab813f12ad0..73985cf31e0f9 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -11,7 +11,7 @@ use smallvec::{self, SmallVec}; type TypeWalkerStack<'tcx> = SmallVec<[GenericArg<'tcx>; 8]>; pub struct TypeWalker<'tcx> { - tcx: TyCtxt<'tcx>, + expose_default_const_substs: Option>, stack: TypeWalkerStack<'tcx>, last_subtree: usize, pub visited: SsoHashSet>, @@ -26,8 +26,13 @@ pub struct TypeWalker<'tcx> { /// It maintains a set of visited types and /// skips any types that are already there. impl<'tcx> TypeWalker<'tcx> { - fn new(tcx: TyCtxt<'tcx>, root: GenericArg<'tcx>) -> Self { - Self { tcx, stack: smallvec![root], last_subtree: 1, visited: SsoHashSet::new() } + fn new(expose_default_const_substs: Option>, root: GenericArg<'tcx>) -> Self { + Self { + expose_default_const_substs, + stack: smallvec![root], + last_subtree: 1, + visited: SsoHashSet::new(), + } } /// Skips the subtree corresponding to the last type @@ -56,7 +61,7 @@ impl<'tcx> Iterator for TypeWalker<'tcx> { let next = self.stack.pop()?; self.last_subtree = self.stack.len(); if self.visited.insert(next) { - push_inner(self.tcx, &mut self.stack, next); + push_inner(self.expose_default_const_substs, &mut self.stack, next); debug!("next: stack={:?}", self.stack); return Some(next); } @@ -76,7 +81,7 @@ impl GenericArg<'tcx> { /// [isize] => { [isize], isize } /// ``` pub fn walk(self, tcx: TyCtxt<'tcx>) -> TypeWalker<'tcx> { - TypeWalker::new(tcx, self) + TypeWalker::new(Some(tcx), self) } /// Iterator that walks the immediate children of `self`. Hence @@ -92,13 +97,17 @@ impl GenericArg<'tcx> { visited: &mut SsoHashSet>, ) -> impl Iterator> { let mut stack = SmallVec::new(); - push_inner(tcx, &mut stack, self); + push_inner(Some(tcx), &mut stack, self); stack.retain(|a| visited.insert(*a)); stack.into_iter() } } impl<'tcx> super::TyS<'tcx> { + pub fn walk_ignoring_default_const_substs(&'tcx self) -> TypeWalker<'tcx> { + TypeWalker::new(None, self.into()) + } + /// Iterator that walks `self` and any types reachable from /// `self`, in depth-first order. Note that just walks the types /// that appear in `self`, it does not descend into the fields of @@ -110,7 +119,7 @@ impl<'tcx> super::TyS<'tcx> { /// [isize] => { [isize], isize } /// ``` pub fn walk(&'tcx self, tcx: TyCtxt<'tcx>) -> TypeWalker<'tcx> { - TypeWalker::new(tcx, self.into()) + TypeWalker::new(Some(tcx), self.into()) } } @@ -121,7 +130,7 @@ impl<'tcx> super::TyS<'tcx> { /// natural order one would expect (basically, the order of the /// types as they are written). fn push_inner<'tcx>( - tcx: TyCtxt<'tcx>, + expose_default_const_substs: Option>, stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>, ) { @@ -202,7 +211,11 @@ fn push_inner<'tcx>( | ty::ConstKind::Error(_) => {} ty::ConstKind::Unevaluated(ct) => { - stack.extend(ct.substs(tcx).iter().rev()); + if let Some(tcx) = expose_default_const_substs { + stack.extend(ct.substs(tcx).iter().rev()); + } else if let Some(substs) = ct.substs_ { + stack.extend(substs.iter().rev()); + } } } } diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 1c7f88c0bb611..f3f22cb05670c 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -114,7 +114,12 @@ fn insert_required_predicates_to_be_wf<'tcx>( required_predicates: &mut RequiredPredicates<'tcx>, explicit_map: &mut ExplicitPredicatesMap<'tcx>, ) { - for arg in field_ty.walk(tcx) { + // We must not look into the default substs of consts + // as computing those depends on the results of `predicates_of`. + // + // Luckily the only types contained in default substs are type + // parameters which don't matter here. + for arg in field_ty.walk_ignoring_default_const_substs() { let ty = match arg.unpack() { GenericArgKind::Type(ty) => ty,