From e8150fa60cc445de7a57db634deb0668880be593 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 27 Sep 2022 11:59:25 +0200 Subject: [PATCH] mir constants: type traversing bye bye --- compiler/rustc_borrowck/src/renumber.rs | 26 +----------- compiler/rustc_infer/src/infer/resolve.rs | 5 --- compiler/rustc_middle/src/mir/mod.rs | 8 ++-- .../rustc_middle/src/mir/type_foldable.rs | 42 ++----------------- .../rustc_middle/src/mir/type_visitable.rs | 32 ++------------ compiler/rustc_middle/src/ty/erase_regions.rs | 5 --- compiler/rustc_middle/src/ty/fold.rs | 40 ------------------ .../src/ty/normalize_erasing_regions.rs | 21 ---------- compiler/rustc_middle/src/ty/subst.rs | 6 --- compiler/rustc_middle/src/ty/visit.rs | 25 ----------- .../rustc_monomorphize/src/polymorphize.rs | 40 +++++++----------- .../src/traits/query/normalize.rs | 8 ---- 12 files changed, 26 insertions(+), 232 deletions(-) diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index d737432f0ef68..f3023769081f2 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -1,8 +1,8 @@ use rustc_index::vec::IndexVec; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_middle::mir::visit::{MutVisitor, TyContext}; +use rustc_middle::mir::Constant; use rustc_middle::mir::{Body, Location, Promoted}; -use rustc_middle::mir::{Constant, ConstantKind}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -38,21 +38,6 @@ where }) } -// FIXME(valtrees): This function is necessary because `fold_regions` -// panics for mir constants in the visitor. -// -// Once `visit_mir_constant` is removed we can also remove this function -// and just use `renumber_regions`. -fn renumber_regions_in_mir_constant<'tcx>( - infcx: &InferCtxt<'tcx>, - value: ConstantKind<'tcx>, -) -> ConstantKind<'tcx> { - infcx.tcx.super_fold_regions(value, |_region, _depth| { - let origin = NllRegionVariableOrigin::Existential { from_forall: false }; - infcx.next_nll_region_var(origin) - }) -} - struct NllVisitor<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } @@ -64,13 +49,6 @@ impl<'a, 'tcx> NllVisitor<'a, 'tcx> { { renumber_regions(self.infcx, value) } - - fn renumber_regions_in_mir_constant( - &mut self, - value: ConstantKind<'tcx>, - ) -> ConstantKind<'tcx> { - renumber_regions_in_mir_constant(self.infcx, value) - } } impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { @@ -103,7 +81,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) { let literal = constant.literal; - constant.literal = self.renumber_regions_in_mir_constant(literal); + constant.literal = self.renumber_regions(literal); debug!("constant: {:#?}", constant); } } diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 069f96000918f..4db4ff2388d77 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,6 +1,5 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::{FixupError, FixupResult, InferCtxt, Span}; -use rustc_middle::mir; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor}; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable, TypeVisitable}; @@ -48,10 +47,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { ct.super_fold_with(self) } } - - fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { - constant.super_fold_with(self) - } } /// The opportunistic region resolver opportunistically resolves regions diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c022ea9e5b470..f94c447e8fb9e 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -7,9 +7,9 @@ use crate::mir::interpret::{ }; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use crate::ty::visit::{TypeVisitable, TypeVisitor}; use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex}; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; @@ -2056,7 +2056,7 @@ pub struct Constant<'tcx> { } #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable, Debug)] -#[derive(Lift)] +#[derive(Lift, TypeFoldable, TypeVisitable)] pub enum ConstantKind<'tcx> { /// This constant came from the type system Ty(ty::Const<'tcx>), @@ -2448,7 +2448,7 @@ impl<'tcx> ConstantKind<'tcx> { /// An unevaluated (potentially generic) constant used in MIR. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] -#[derive(Hash, HashStable)] +#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct UnevaluatedConst<'tcx> { pub def: ty::WithOptConstParam, pub substs: SubstsRef<'tcx>, diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 8e18cad442ed9..4d7d464d7cd90 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -3,7 +3,6 @@ use rustc_ast::InlineAsmTemplatePiece; use super::*; -use crate::mir; use crate::ty; TrivialTypeTraversalAndLiftImpls! { @@ -51,43 +50,8 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { } } -impl<'tcx> TypeFoldable<'tcx> for mir::UnevaluatedConst<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { - folder.try_fold_mir_unevaluated(self) - } -} - -impl<'tcx> TypeSuperFoldable<'tcx> for mir::UnevaluatedConst<'tcx> { - fn try_super_fold_with>( - self, - folder: &mut F, - ) -> Result { - Ok(mir::UnevaluatedConst { - def: self.def, - substs: self.substs.try_fold_with(folder)?, - promoted: self.promoted, - }) - } -} - -impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { - #[inline(always)] - fn try_fold_with>(self, folder: &mut F) -> Result { - folder.try_fold_mir_const(self) - } -} - -impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> { - fn try_super_fold_with>( - self, - folder: &mut F, - ) -> Result { - match self { - ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)), - ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)), - ConstantKind::Unevaluated(uv, t) => { - Ok(ConstantKind::Unevaluated(uv.try_fold_with(folder)?, t.try_fold_with(folder)?)) - } - } +impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { + fn try_fold_with>(self, _: &mut F) -> Result { + Ok(self) } } diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index a136ca4d8c37f..fd3773f226490 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -1,7 +1,6 @@ //! `TypeVisitable` implementations for MIR types use super::*; -use crate::mir; impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix { fn visit_with>(&self, _: &mut V) -> ControlFlow { @@ -9,33 +8,8 @@ impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix { } } -impl<'tcx> TypeVisitable<'tcx> for mir::UnevaluatedConst<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - visitor.visit_mir_unevaluated(*self) - } -} - -impl<'tcx> TypeSuperVisitable<'tcx> for mir::UnevaluatedConst<'tcx> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.substs.visit_with(visitor) - } -} - -impl<'tcx> TypeVisitable<'tcx> for ConstantKind<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - visitor.visit_mir_const(*self) - } -} - -impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { - match *self { - ConstantKind::Ty(c) => c.visit_with(visitor), - ConstantKind::Val(_, t) => t.visit_with(visitor), - ConstantKind::Unevaluated(uv, t) => { - uv.visit_with(visitor)?; - t.visit_with(visitor) - } - } +impl<'tcx> TypeVisitable<'tcx> for ConstValue<'tcx> { + fn visit_with>(&self, _: &mut V) -> ControlFlow { + ControlFlow::CONTINUE } } diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 3226950e79e13..ffdac93bcd09a 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,4 +1,3 @@ -use crate::mir; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::ty::visit::TypeVisitable; use crate::ty::{self, Ty, TyCtxt, TypeFlags}; @@ -67,8 +66,4 @@ impl<'tcx> TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { _ => self.tcx.lifetimes.re_erased, } } - - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { - c.super_fold_with(self) - } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index ce4a46e362d80..f456999ae3eb2 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -42,7 +42,6 @@ //! - ty.super_fold_with(folder) //! - u.fold_with(folder) //! ``` -use crate::mir; use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitable}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; @@ -134,20 +133,9 @@ pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> { uv.super_fold_with(self) } - fn fold_mir_unevaluated( - &mut self, - uv: mir::UnevaluatedConst<'tcx>, - ) -> mir::UnevaluatedConst<'tcx> { - uv.super_fold_with(self) - } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { p.super_fold_with(self) } - - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { - bug!("most type folders should not be folding MIR datastructures: {:?}", c) - } } /// This trait is implemented for every folding traversal. There is a fold @@ -188,26 +176,12 @@ pub trait FallibleTypeFolder<'tcx>: Sized { c.try_super_fold_with(self) } - fn try_fold_mir_unevaluated( - &mut self, - c: mir::UnevaluatedConst<'tcx>, - ) -> Result, Self::Error> { - c.try_super_fold_with(self) - } - fn try_fold_predicate( &mut self, p: ty::Predicate<'tcx>, ) -> Result, Self::Error> { p.try_super_fold_with(self) } - - fn try_fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result, Self::Error> { - bug!("most type folders should not be folding MIR datastructures: {:?}", c) - } } // This blanket implementation of the fallible trait for infallible folders @@ -248,23 +222,9 @@ where Ok(self.fold_ty_unevaluated(c)) } - fn try_fold_mir_unevaluated( - &mut self, - c: mir::UnevaluatedConst<'tcx>, - ) -> Result, !> { - Ok(self.fold_mir_unevaluated(c)) - } - fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result, !> { Ok(self.fold_predicate(p)) } - - fn try_fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result, !> { - Ok(self.fold_mir_const(c)) - } } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index fe303e21b658d..ee13920d52edd 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -214,15 +214,6 @@ impl<'tcx> TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const() } - - #[inline] - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { - // FIXME: This *probably* needs canonicalization too! - let arg = self.param_env.and(c); - self.tcx - .try_normalize_mir_const_after_erasing_regions(arg) - .unwrap_or_else(|_| bug!("failed to normalize {:?}", c)) - } } struct TryNormalizeAfterErasingRegionsFolder<'tcx> { @@ -267,16 +258,4 @@ impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'t Err(_) => Err(NormalizationError::Const(c)), } } - - fn try_fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result, Self::Error> { - // FIXME: This *probably* needs canonicalization too! - let arg = self.param_env.and(c); - match self.tcx.try_normalize_mir_const_after_erasing_regions(arg) { - Ok(c) => Ok(c), - Err(_) => Err(NormalizationError::ConstantKind(c)), - } - } } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index e552d3f1cc551..c2a83ca9dbb83 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -1,6 +1,5 @@ // Type substitutions. -use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; @@ -662,11 +661,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { c.super_fold_with(self) } } - - #[inline] - fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { - c.super_fold_with(self) - } } impl<'a, 'tcx> SubstFolder<'a, 'tcx> { diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 6e1991b527fe3..5ca00a11ab9f4 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -38,7 +38,6 @@ //! - ty.super_visit_with(visitor) //! - u.visit_with(visitor) //! ``` -use crate::mir; use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; use rustc_errors::ErrorGuaranteed; @@ -205,20 +204,9 @@ pub trait TypeVisitor<'tcx>: Sized { uv.super_visit_with(self) } - fn visit_mir_unevaluated( - &mut self, - uv: mir::UnevaluatedConst<'tcx>, - ) -> ControlFlow { - uv.super_visit_with(self) - } - fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow { p.super_visit_with(self) } - - fn visit_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> ControlFlow { - c.super_visit_with(self) - } } /////////////////////////////////////////////////////////////////////////// @@ -619,19 +607,6 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } } - fn visit_mir_unevaluated( - &mut self, - uv: mir::UnevaluatedConst<'tcx>, - ) -> ControlFlow { - let flags = FlagComputation::for_unevaluated_const(uv.shrink()); - trace!(r.flags=?flags); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::CONTINUE - } - } - #[inline] #[instrument(level = "trace", ret)] fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index a93f6a60114a6..650076c2213a3 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -276,9 +276,21 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { ConstantKind::Ty(c) => { c.visit_with(self); } - ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => { - Visitor::visit_ty(self, ty, TyContext::Location(location)) + ConstantKind::Unevaluated(mir::UnevaluatedConst { def, substs: _, promoted }, ty) => { + // Avoid considering `T` unused when constants are of the form: + // `>::foo::promoted[p]` + if let Some(p) = promoted { + if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self { + // If there is a promoted, don't look at the substs - since it will always contain + // the generic parameters, instead, traverse the promoted MIR. + let promoted = self.tcx.promoted_mir(def.did); + self.visit_body(&promoted[p]); + } + } + + Visitor::visit_ty(self, ty, TyContext::Location(location)); } + ConstantKind::Val(_, ty) => Visitor::visit_ty(self, ty, TyContext::Location(location)), } } @@ -310,30 +322,6 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } } - fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow { - if !constant.has_non_region_param() { - return ControlFlow::CONTINUE; - } - - match constant { - ConstantKind::Ty(ct) => ct.visit_with(self), - ConstantKind::Unevaluated(mir::UnevaluatedConst { def, substs: _, promoted: Some(p) }, _) - // Avoid considering `T` unused when constants are of the form: - // `>::foo::promoted[p]` - if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self => - { - // If there is a promoted, don't look at the substs - since it will always contain - // the generic parameters, instead, traverse the promoted MIR. - let promoted = self.tcx.promoted_mir(def.did); - self.visit_body(&promoted[p]); - ControlFlow::CONTINUE - } - ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => { - constant.super_visit_with(self) - } - } - } - #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { if !ty.has_non_region_param() { diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index af1029521726a..aa8094a60dd08 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -11,7 +11,6 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::traits::Normalized; -use rustc_middle::mir; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; @@ -347,13 +346,6 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { )) } - fn try_fold_mir_const( - &mut self, - constant: mir::ConstantKind<'tcx>, - ) -> Result, Self::Error> { - constant.try_super_fold_with(self) - } - #[inline] fn try_fold_predicate( &mut self,