diff options
| author | b-naber <bn263@gmx.de> | 2022-06-27 16:32:47 +0200 |
|---|---|---|
| committer | b-naber <bn263@gmx.de> | 2022-09-13 17:40:59 +0200 |
| commit | a4bbb8db5c4c702265b8afcc1313684a127ddd6a (patch) | |
| tree | f1643aa200cd35761c02faf68189ec86276fb0d9 | |
| parent | 7098c181f8447810fadb1776d3ffa3cdc93ce402 (diff) | |
| download | rust-a4bbb8db5c4c702265b8afcc1313684a127ddd6a.tar.gz rust-a4bbb8db5c4c702265b8afcc1313684a127ddd6a.zip | |
use ty::Unevaluated<'tcx, ()> in type system
32 files changed, 301 insertions, 189 deletions
diff --git a/Cargo.lock b/Cargo.lock index 4e0e72d3415..36bd77c5d93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,7 +288,7 @@ dependencies = [ [[package]] name = "cargo" -version = "0.66.0" +version = "0.65.0" dependencies = [ "anyhow", "atty", @@ -299,6 +299,7 @@ dependencies = [ "cargo-util", "clap", "crates-io", + "crossbeam-utils", "curl", "curl-sys", "env_logger 0.9.0", @@ -322,6 +323,7 @@ dependencies = [ "libgit2-sys", "log", "memchr", + "num_cpus", "opener", "openssl", "os_info", @@ -381,7 +383,6 @@ dependencies = [ name = "cargo-miri" version = "0.1.0" dependencies = [ - "cargo_metadata 0.15.0", "directories", "rustc-workspace-hack", "rustc_version", @@ -430,7 +431,6 @@ dependencies = [ "termcolor", "toml_edit", "url", - "winapi", ] [[package]] @@ -1004,6 +1004,16 @@ dependencies = [ ] [[package]] +name = "ctor" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +dependencies = [ + "quote", + "syn", +] + +[[package]] name = "curl" version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1560,9 +1570,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.15.0" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1" +checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" dependencies = [ "bitflags", "libc", @@ -1575,9 +1585,9 @@ dependencies = [ [[package]] name = "git2-curl" -version = "0.16.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed817a00721e2f8037ba722e60358d4956dae9cca10315fc982f967907d3b0cd" +checksum = "1ee51709364c341fbb6fe2a385a290fb9196753bdde2fc45447d27cd31b11b13" dependencies = [ "curl", "git2", @@ -1935,29 +1945,10 @@ dependencies = [ ] [[package]] -name = "libffi" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e454b3efb16fba3b17810ae5e41df02b649e564ab3c5a34b3b93ed07ad287e6" -dependencies = [ - "libc", - "libffi-sys", -] - -[[package]] -name = "libffi-sys" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4106b7f09d7b87d021334d5618fac1dfcfb824d4c5fe111ff0074dfd242e15" -dependencies = [ - "cc", -] - -[[package]] name = "libgit2-sys" -version = "0.14.0+1.5.0" +version = "0.13.4+1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b" +checksum = "d0fa6563431ede25f5cc7f6d803c6afbc1c5d3ad3d4925d12c882bf2b526f5d1" dependencies = [ "cc", "libc", @@ -2247,8 +2238,6 @@ dependencies = [ "getrandom 0.2.0", "lazy_static", "libc", - "libffi", - "libloading", "log", "measureme", "rand 0.8.5", @@ -2422,6 +2411,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" [[package]] +name = "output_vt100" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" +dependencies = [ + "winapi", +] + +[[package]] name = "owo-colors" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2663,6 +2661,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] +name = "pretty_assertions" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" +dependencies = [ + "ctor", + "diff", + "output_vt100", + "yansi", +] + +[[package]] name = "pretty_env_logger" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4540,9 +4550,9 @@ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e" [[package]] name = "snapbox" -version = "0.3.3" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7" +checksum = "767a1d5da232b6959cd1bd5c9e8db8a7cce09c3038e89deedb49a549a2aefd93" dependencies = [ "concolor", "content_inspector", @@ -4558,9 +4568,9 @@ dependencies = [ [[package]] name = "snapbox-macros" -version = "0.3.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a253e6f894cfa440cba00600a249fa90869d8e0ec45ab274a456e043a0ce8f2" +checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930" [[package]] name = "socket2" @@ -5039,16 +5049,14 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "ui_test" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1f546a5883ae78da735bba529ec1116661e2f73582f23920d994dc97da3a22" +version = "0.1.0" dependencies = [ "cargo_metadata 0.15.0", "color-eyre", "colored", "crossbeam", - "diff", "lazy_static", + "pretty_assertions", "regex", "rustc_version", "serde", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index fc0e95f30c9..ed9ede029a8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -354,11 +354,13 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { let tcx = self.tcx(); let maybe_uneval = match constant.literal { ConstantKind::Ty(ct) => match ct.kind() { - ty::ConstKind::Unevaluated(uv) => Some(uv), + ty::ConstKind::Unevaluated(uv) => Some(uv.expand()), _ => None, }, + ConstantKind::Unevaluated(uv, _) => Some(uv), _ => None, }; + if let Some(uv) = maybe_uneval { if let Some(promoted) = uv.promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, @@ -1813,11 +1815,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Operand::Constant(constant) = op { let maybe_uneval = match constant.literal { ConstantKind::Ty(ct) => match ct.kind() { - ty::ConstKind::Unevaluated(uv) => Some(uv), + ty::ConstKind::Unevaluated(uv) => Some(uv.expand()), _ => None, }, + ConstantKind::Unevaluated(uv, _) => Some(uv), _ => None, }; + if let Some(uv) = maybe_uneval { if uv.promoted.is_none() { let tcx = self.tcx(); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 0305341da78..7bf578b6a4e 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -124,11 +124,7 @@ pub(crate) fn codegen_constant<'tcx>( ) -> CValue<'tcx> { let const_ = match fx.monomorphize(constant.literal) { ConstantKind::Ty(ct) => ct, - ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty), - }; - let const_val = match const_.kind() { - ConstKind::Value(valtree) => fx.tcx.valtree_to_const_val((const_.ty(), valtree)), - ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + ConstantKind::Unevaluated(mir::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { assert!(substs.is_empty()); @@ -136,7 +132,7 @@ pub(crate) fn codegen_constant<'tcx>( return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty())).to_cvalue(fx); } - ConstKind::Unevaluated(unevaluated) => { + ConstantKind::Unevaluated(unevaluated) => { match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { Ok(const_val) => const_val, Err(_) => { @@ -144,6 +140,17 @@ pub(crate) fn codegen_constant<'tcx>( } } } + ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty), + }; + let const_val = match const_.kind() { + ConstKind::Value(valtree) => fx.tcx.valtree_to_const_val((const_.ty(), valtree)), + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if fx.tcx.is_static(def.did) => + { + assert!(substs.is_empty()); + assert!(promoted.is_none()); + return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty())).to_cvalue(fx); + } ConstKind::Param(_) | ConstKind::Infer(_) | ConstKind::Bound(_, _) diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 9a995fbf65c..4c6ab457c49 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -25,26 +25,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result<ConstValue<'tcx>, ErrorHandled> { let ct = self.monomorphize(constant.literal); - let ct = match ct { - mir::ConstantKind::Ty(ct) => ct, + let uv = match ct { + mir::ConstantKind::Ty(ct) => match ct.kind() { + ty::ConstKind::Unevaluated(uv) => uv.expand(), + ty::ConstKind::Value(val) => { + return Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))); + } + err => span_bug!( + constant.span, + "encountered bad ConstKind after monomorphizing: {:?}", + err + ), + }, + mir::ConstantKind::Unevaluated(uv, _) => uv, mir::ConstantKind::Val(val, _) => return Ok(val), }; - match ct.kind() { - ty::ConstKind::Unevaluated(ct) => self - .cx - .tcx() - .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None) - .map_err(|err| { - self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); - err - }), - ty::ConstKind::Value(val) => Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val))), - err => span_bug!( - constant.span, - "encountered bad ConstKind after monomorphizing: {:?}", - err - ), - } + + self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| { + self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); + err + }) } /// process constant containing SIMD shuffle indices diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index f6c4f7dd112..9784de1fffc 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -565,7 +565,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } ty::ConstKind::Unevaluated(uv) => { let instance = self.resolve(uv.def, uv.substs)?; - Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) + Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into()) } ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => { span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c) @@ -578,6 +578,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } + /// Tries to evaluate an unevaluated constant from the MIR (and not the type-system). + #[inline] + pub fn uneval_to_op( + &self, + uneval: &ty::Unevaluated<'tcx>, + ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { + let instance = self.resolve(uneval.def, uneval.substs)?; + Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into()) + } + pub fn mir_const_to_op( &self, val: &mir::ConstantKind<'tcx>, @@ -586,6 +596,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match val { mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout), mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout), + mir::ConstantKind::Unevaluated(uv, _) => self.uneval_to_op(uv), } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 45dadcfff2e..fce799d47ec 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -347,14 +347,15 @@ where // Check the qualifs of the value of `const` items. if let Some(ct) = constant.literal.const_for_ty() { - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.kind() + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: _ }) = + ct.kind() { // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible // only for `NeedsNonConstDrop` with precise drop checking. This is the only const // check performed after the promotion. Verify that with an assertion. - assert!(promoted.is_none() || Q::ALLOW_PROMOTED); + // Don't peek inside trait associated constants. - if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() { + if cx.tcx.trait_of_item(def.did).is_none() { let qualifs = if let Some((did, param_did)) = def.as_const_arg() { cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did)) } else { diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f5ba408bee0..f7a7cc88a52 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -840,21 +840,15 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did)); - let _const = tcx.mk_const(ty::ConstS { - ty, - kind: ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted: Some(promoted_id), - }), - }); + let uneval = ty::Unevaluated { def, substs, promoted: Some(promoted_id) }; Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: ConstantKind::from_const(_const, tcx), + literal: ConstantKind::Unevaluated(uneval, ty), })) }; + let blocks = self.source.basic_blocks.as_mut(); let local_decls = &mut self.source.local_decls; let loc = candidate.location; diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 524383e381f..c406df9e411 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -743,7 +743,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - assert_eq!(promoted, None); + assert_eq!(promoted, ()); + let substs = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), @@ -964,13 +965,15 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - assert_eq!(promoted, None); + assert_eq!(promoted, ()); + let substs = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), substs, substs, )?; + Ok(self.tcx().mk_const(ty::ConstS { ty: c.ty(), kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bbbc044b85a..7bd8f423a01 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1673,7 +1673,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn try_const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, - unevaluated: ty::Unevaluated<'tcx>, + unevaluated: ty::Unevaluated<'tcx, ()>, ty: Ty<'tcx>, span: Option<Span>, ) -> Result<ty::Const<'tcx>, ErrorHandled> { @@ -1708,7 +1708,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn const_eval_resolve( &self, mut param_env: ty::ParamEnv<'tcx>, - unevaluated: ty::Unevaluated<'tcx>, + unevaluated: ty::Unevaluated<'tcx, ()>, span: Option<Span>, ) -> EvalToValTreeResult<'tcx> { let mut substs = self.resolve_vars_if_possible(unevaluated.substs); @@ -1739,11 +1739,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!(?param_env_erased); debug!(?substs_erased); - let unevaluated = ty::Unevaluated { - def: unevaluated.def, - substs: substs_erased, - promoted: unevaluated.promoted, - }; + let unevaluated = + ty::Unevaluated { def: unevaluated.def, substs: substs_erased, promoted: () }; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 786927e2dad..4207988d700 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -63,7 +63,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn const_eval_resolve_for_typeck( self, param_env: ty::ParamEnv<'tcx>, - ct: ty::Unevaluated<'tcx>, + ct: ty::Unevaluated<'tcx, ()>, span: Option<Span>, ) -> EvalToValTreeResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference @@ -78,7 +78,7 @@ impl<'tcx> TyCtxt<'tcx> { match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { Ok(Some(instance)) => { - let cid = GlobalId { instance, promoted: ct.promoted }; + let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id_for_typeck(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index dd768c5358d..7c9b1e492d9 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -3,7 +3,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html use crate::mir::interpret::{ - AllocRange, ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar, + AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, LitToConstInput, Scalar, }; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -2061,6 +2061,10 @@ pub struct Constant<'tcx> { pub enum ConstantKind<'tcx> { /// This constant came from the type system Ty(ty::Const<'tcx>), + + /// An unevaluated constant that cannot go back into the type system. + Unevaluated(ty::Unevaluated<'tcx, Option<Promoted>>, Ty<'tcx>), + /// This constant cannot go back into the type system, as it represents /// something the type system cannot handle (e.g. pointers). Val(interpret::ConstValue<'tcx>, Ty<'tcx>), @@ -2091,7 +2095,7 @@ impl<'tcx> ConstantKind<'tcx> { pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> { match self { ConstantKind::Ty(c) => Some(*c), - ConstantKind::Val(..) => None, + ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => None, } } @@ -2099,7 +2103,7 @@ impl<'tcx> ConstantKind<'tcx> { pub fn ty(&self) -> Ty<'tcx> { match self { ConstantKind::Ty(c) => c.ty(), - ConstantKind::Val(_, ty) => *ty, + ConstantKind::Val(_, ty) | ConstantKind::Unevaluated(_, ty) => *ty, } } @@ -2111,6 +2115,7 @@ impl<'tcx> ConstantKind<'tcx> { _ => None, }, ConstantKind::Val(val, _) => Some(val), + ConstantKind::Unevaluated(..) => None, } } @@ -2125,6 +2130,7 @@ impl<'tcx> ConstantKind<'tcx> { _ => None, }, ConstantKind::Val(val, _) => val.try_to_scalar(), + ConstantKind::Unevaluated(..) => None, } } @@ -2157,6 +2163,14 @@ impl<'tcx> ConstantKind<'tcx> { } } Self::Val(_, _) => self, + Self::Unevaluated(uneval, ty) => { + // FIXME: We might want to have a `try_eval`-like function on `Unevaluated` + match tcx.const_eval_resolve(param_env, uneval, None) { + Ok(val) => Self::Val(val, ty), + Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self, + Err(_) => Self::Ty(tcx.const_error(ty)), + } + } } } @@ -2182,6 +2196,18 @@ impl<'tcx> ConstantKind<'tcx> { tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; val.try_to_bits(size) } + Self::Unevaluated(uneval, ty) => { + match tcx.const_eval_resolve(param_env, *uneval, None) { + Ok(val) => { + let size = tcx + .layout_of(param_env.with_reveal_all_normalized(tcx).and(*ty)) + .ok()? + .size; + val.try_to_bits(size) + } + Err(_) => None, + } + } } } @@ -2190,6 +2216,12 @@ impl<'tcx> ConstantKind<'tcx> { match self { Self::Ty(ct) => ct.try_eval_bool(tcx, param_env), Self::Val(val, _) => val.try_to_bool(), + Self::Unevaluated(uneval, _) => { + match tcx.const_eval_resolve(param_env, *uneval, None) { + Ok(val) => val.try_to_bool(), + Err(_) => None, + } + } } } @@ -2198,6 +2230,12 @@ impl<'tcx> ConstantKind<'tcx> { match self { Self::Ty(ct) => ct.try_eval_usize(tcx, param_env), Self::Val(val, _) => val.try_to_machine_usize(tcx), + Self::Unevaluated(uneval, _) => { + match tcx.const_eval_resolve(param_env, *uneval, None) { + Ok(val) => val.try_to_machine_usize(tcx), + Err(_) => None, + } + } } } @@ -2293,15 +2331,16 @@ impl<'tcx> ConstantKind<'tcx> { let substs = ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty }) .substs; - debug_assert!(!substs.has_free_regions()); - Self::Ty(tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(ty::Unevaluated { - def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs, - promoted: None, - }), - ty, - })) + + let uneval = ty::Unevaluated { + def: ty::WithOptConstParam::unknown(def_id).to_global(), + substs, + promoted: None, + }; + + debug_assert!(!uneval.has_free_regions()); + + Self::Unevaluated(uneval, ty) } #[instrument(skip(tcx), level = "debug", ret)] @@ -2398,7 +2437,7 @@ impl<'tcx> ConstantKind<'tcx> { kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), - promoted: None, + promoted: (), }), ty, })) @@ -2412,6 +2451,7 @@ impl<'tcx> ConstantKind<'tcx> { let const_val = tcx.valtree_to_const_val((c.ty(), valtree)); Self::Val(const_val, c.ty()) } + ty::ConstKind::Unevaluated(uv) => Self::Unevaluated(uv.expand(), c.ty()), _ => Self::Ty(c), } } @@ -2612,6 +2652,10 @@ impl<'tcx> Display for ConstantKind<'tcx> { match *self { ConstantKind::Ty(c) => pretty_print_const(c, fmt, true), ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true), + ConstantKind::Unevaluated(..) => { + fmt.write_str("_")?; + Ok(()) + } } } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 88c16189f1d..3c559e2fe20 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -464,12 +464,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { let val = match literal { ConstantKind::Ty(ct) => match ct.kind() { ty::ConstKind::Param(p) => format!("Param({})", p), - ty::ConstKind::Unevaluated(uv) => format!( - "Unevaluated({}, {:?}, {:?})", - self.tcx.def_path_str(uv.def.did), - uv.substs, - uv.promoted, - ), + ty::ConstKind::Unevaluated(uv) => { + format!( + "Unevaluated({}, {:?}, {:?})", + self.tcx.def_path_str(uv.def.did), + uv.substs, + uv.promoted, + ) + } ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)), ty::ConstKind::Error(_) => "Error".to_string(), // These variants shouldn't exist in the MIR. @@ -477,6 +479,14 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { | ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) => bug!("unexpected MIR constant: {:?}", literal), }, + ConstantKind::Unevaluated(uv, _) => { + format!( + "Unevaluated({}, {:?}, {:?})", + self.tcx.def_path_str(uv.def.did), + uv.substs, + uv.promoted, + ) + } // To keep the diffs small, we render this like we render `ty::Const::Value`. // // This changes once `ty::Const::Value` is represented using valtrees. @@ -702,6 +712,7 @@ pub fn write_allocations<'tcx>( ConstantKind::Val(val, _) => { self.0.extend(alloc_ids_from_const_val(val)); } + ConstantKind::Unevaluated(..) => {} } } } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 82a6b0c506f..e5aadac8739 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -235,6 +235,9 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> { 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, t.try_fold_with(folder)?)) + } } } } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 708ea4398c8..6dde8c8b65d 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -879,6 +879,7 @@ macro_rules! make_mir_visitor { match literal { ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location), ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), + ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), } } diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index bed809930da..8f79b4705ad 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -42,7 +42,7 @@ impl<'tcx> AbstractConst<'tcx> { ct: ty::Const<'tcx>, ) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> { match ct.kind() { - ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()), + ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv), ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported), _ => Ok(None), } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 2eb5cffa6bc..339ff4d3593 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -41,7 +41,7 @@ pub struct ConstS<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstS<'_>, 48); +static_assert_size!(ConstS<'_>, 40); impl<'tcx> Const<'tcx> { #[inline] @@ -84,7 +84,7 @@ impl<'tcx> Const<'tcx> { kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), - promoted: None, + promoted: (), }), ty, }), @@ -181,7 +181,7 @@ impl<'tcx> Const<'tcx> { kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id).to_global(), substs, - promoted: None, + promoted: (), }), ty, }) diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ff20da65c01..3c21b89c97d 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -11,6 +11,7 @@ use rustc_macros::HashStable; use rustc_target::abi::Size; use super::ScalarInt; + /// An unevaluated, potentially generic, constant. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] #[derive(Hash, HashStable)] @@ -66,7 +67,7 @@ pub enum ConstKind<'tcx> { /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. - Unevaluated(Unevaluated<'tcx>), + Unevaluated(Unevaluated<'tcx, ()>), /// Used to hold computed value. Value(ty::ValTree<'tcx>), @@ -77,7 +78,7 @@ pub enum ConstKind<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstKind<'_>, 40); +static_assert_size!(ConstKind<'_>, 32); impl<'tcx> ConstKind<'tcx> { #[inline] @@ -184,6 +185,8 @@ impl<'tcx> ConstKind<'tcx> { if let ConstKind::Unevaluated(unevaluated) = self { use crate::mir::interpret::ErrorHandled; + assert_eq!(unevaluated.promoted, ()); + // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` // also does later, but we want to do it before checking for // inference variables. @@ -204,7 +207,7 @@ impl<'tcx> ConstKind<'tcx> { tcx.param_env(unevaluated.def.did).and(ty::Unevaluated { def: unevaluated.def, substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did), - promoted: unevaluated.promoted, + promoted: (), }) } else { param_env_and @@ -228,7 +231,7 @@ impl<'tcx> ConstKind<'tcx> { } } EvalMode::Mir => { - match tcx.const_eval_resolve(param_env, unevaluated, None) { + match tcx.const_eval_resolve(param_env, unevaluated.expand(), None) { // NOTE(eddyb) `val` contains no lifetimes/types/consts, // and we use the original type, so nothing from `substs` // (which may be identity substs, see above), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e9eecfe78d3..afe97e5f92f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1197,15 +1197,9 @@ pub trait PrettyPrinter<'tcx>: } match ct.kind() { - ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs, - promoted: Some(promoted), - }) => { - p!(print_value_path(def.did, substs)); - p!(write("::{:?}", promoted)); - } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + assert_eq!(promoted, ()); + match self.tcx().def_kind(def.did) { DefKind::Static(..) | DefKind::Const | DefKind::AssocConst => { p!(print_value_path(def.did, substs)) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 81476195d29..488d9242b11 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -613,7 +613,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if tcx.features().generic_const_exprs => { - tcx.try_unify_abstract_consts(relation.param_env().and((au.shrink(), bu.shrink()))) + tcx.try_unify_abstract_consts(relation.param_env().and((au, bu))) } // While this is slightly incorrect, it shouldn't matter for `min_const_generics` @@ -622,6 +622,8 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def && au.promoted == bu.promoted => { + assert_eq!(au.promoted, ()); + let substs = relation.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), @@ -632,7 +634,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( kind: ty::ConstKind::Unevaluated(ty::Unevaluated { def: au.def, substs, - promoted: au.promoted, + promoted: (), }), ty: a.ty(), })); diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 4968032b416..ff80f732b40 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -565,23 +565,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let value = value.eval(self.tcx, self.param_env); match value { - mir::ConstantKind::Ty(c) => { - match c.kind() { - ConstKind::Param(_) => { - self.errors.push(PatternError::ConstParamInPattern(span)); - return PatKind::Wild; - } - ConstKind::Unevaluated(_) => { - // If we land here it means the const can't be evaluated because it's `TooGeneric`. - self.tcx - .sess - .span_err(span, "constant pattern depends on a generic parameter"); - return PatKind::Wild; - } - _ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"), + mir::ConstantKind::Ty(c) => match c.kind() { + ConstKind::Param(_) => { + self.errors.push(PatternError::ConstParamInPattern(span)); + return PatKind::Wild; } - } + _ => bug!("Expected ConstKind::Param"), + }, mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind, + mir::ConstantKind::Unevaluated(..) => { + // If we land here it means the const can't be evaluated because it's `TooGeneric`. + self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); + return PatKind::Wild; + } } } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 082d6c9f07e..cd94af2d3c6 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -22,9 +22,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; -use rustc_middle::ty::{ - self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable, -}; +use rustc_middle::ty::{self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable}; use rustc_session::lint; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; @@ -301,18 +299,17 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let err = ConstEvalErr::new(&self.ecx, error, Some(c.span)); if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal { - ConstantKind::Ty(ct) => match ct.kind() { + ConstantKind::Ty(_) => c.literal.needs_subst(), + ConstantKind::Unevaluated( + ty::Unevaluated { def: _, substs: _, promoted: Some(_) }, + _, + ) => { // Promoteds must lint and not error as the user didn't ask for them - ConstKind::Unevaluated(ty::Unevaluated { - def: _, - substs: _, - promoted: Some(_), - }) => true, - // Out of backwards compatibility we cannot report hard errors in unused - // generic functions using associated constants of the generic parameters. - _ => c.literal.needs_subst(), - }, - ConstantKind::Val(_, ty) => ty.needs_subst(), + true + } + ConstantKind::Unevaluated(_, ty) | ConstantKind::Val(_, ty) => { + ty.needs_subst() + } }; if lint_only { // Out of backwards compatibility we cannot report hard errors in unused diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index ba00f16308e..2ad9f582fbe 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -8,7 +8,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; @@ -606,7 +606,9 @@ impl<'tcx> Inliner<'tcx> { caller_body.required_consts.extend( callee_body.required_consts.iter().copied().filter(|&ct| { match ct.literal.const_for_ty() { - Some(ct) => matches!(ct.kind(), ConstKind::Unevaluated(_)), + Some(_) => { + bug!("should never encounter ty::Unevaluated in required_consts") + } None => true, } }), diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs index 827ce0c02ac..022a7a95fa1 100644 --- a/compiler/rustc_mir_transform/src/required_consts.rs +++ b/compiler/rustc_mir_transform/src/required_consts.rs @@ -1,5 +1,5 @@ use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{Constant, Location}; +use rustc_middle::mir::{Constant, ConstantKind, Location}; use rustc_middle::ty::ConstKind; pub struct RequiredConstsVisitor<'a, 'tcx> { @@ -15,8 +15,18 @@ impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> { impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> { fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) { let literal = constant.literal; - if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.kind() { - self.required_consts.push(*constant); + match literal { + ConstantKind::Ty(c) => match c.kind() { + ConstKind::Unevaluated(uv) => { + let literal = ConstantKind::Unevaluated(uv.expand(), c.ty()); + let new_constant = + Constant { span: constant.span, user_ty: constant.user_ty, literal }; + self.required_consts.push(new_constant); + } + _ => {} + }, + ConstantKind::Unevaluated(..) => self.required_consts.push(*constant), + ConstantKind::Val(..) => {} } } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index be74a9d11e3..72fb566aff7 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -767,7 +767,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ty::ConstKind::Unevaluated(ct) => { debug!(?ct); let param_env = ty::ParamEnv::reveal_all(); - match self.tcx.const_eval_resolve(param_env, ct, None) { + match self.tcx.const_eval_resolve(param_env, ct.expand(), None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => val, Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, @@ -780,6 +780,19 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { } _ => return, }, + mir::ConstantKind::Unevaluated(uv, _) => { + let param_env = ty::ParamEnv::reveal_all(); + match self.tcx.const_eval_resolve(param_env, uv, None) { + // The `monomorphize` call should have evaluated that constant already. + Ok(val) => val, + Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, + Err(ErrorHandled::TooGeneric) => span_bug!( + self.body.source_info(location).span, + "collection encountered polymorphic constant: {:?}", + literal + ), + } + } }; collect_const_value(self.tcx, val, self.output); self.visit_ty(literal.ty(), TyContext::Location(location)); @@ -798,7 +811,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { collect_const_value(self.tcx, const_val, self.output) } ty::ConstKind::Unevaluated(unevaluated) => { - match self.tcx.const_eval_resolve(param_env, unevaluated, None) { + match self.tcx.const_eval_resolve(param_env, unevaluated.expand(), None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => span_bug!( self.body.source_info(location).span, diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 98156a94ec4..d083a3e00b6 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -9,7 +9,7 @@ use rustc_hir::{def::DefKind, def_id::DefId, ConstContext}; use rustc_index::bit_set::FiniteBitSet; use rustc_middle::mir::{ visit::{TyContext, Visitor}, - Local, LocalDecl, Location, + ConstantKind, Local, LocalDecl, Location, }; use rustc_middle::ty::{ self, @@ -292,7 +292,29 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)}) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if matches!( + self.tcx.def_kind(def.did), + DefKind::AnonConst | DefKind::InlineConst + ) => + { + assert_eq!(promoted, ()); + + self.visit_child_body(def.did, substs); + ControlFlow::CONTINUE + } + _ => c.super_visit_with(self), + } + } + + fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow<Self::BreakTy> { + if !constant.has_param_types_or_consts() { + return ControlFlow::CONTINUE; + } + + match constant { + ConstantKind::Ty(_) => constant.super_visit_with(self), + ConstantKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p) }, _) // Avoid considering `T` unused when constants are of the form: // `<Self as Foo<T>>::foo::promoted[p]` if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self => @@ -303,13 +325,9 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.visit_body(&promoted[p]); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(uv) - if matches!(self.tcx.def_kind(uv.def.did), DefKind::AnonConst | DefKind::InlineConst) => - { - self.visit_child_body(uv.def.did, uv.substs); - ControlFlow::CONTINUE + ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => { + constant.super_visit_with(self) } - _ => c.super_visit_with(self), } } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 254bc4ab663..5a213987e87 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -183,7 +183,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( FailureKind::Concrete => {} } } - let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); + let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); match concrete { Err(ErrorHandled::TooGeneric) => { Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug( @@ -210,7 +210,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( // and hopefully soon change this to an error. // // See #74595 for more details about this. - let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); + let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); match concrete { // If we're evaluating a foreign constant, under a nightly compiler without generic diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 3763a98c488..6bb6aef1d05 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -509,11 +509,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.kind(), c2.kind()) { - if infcx.try_unify_abstract_consts( - a.shrink(), - b.shrink(), - obligation.param_env, - ) { + if infcx.try_unify_abstract_consts(a, b, obligation.param_env) { return ProcessResult::Changed(vec![]); } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index f65fc5bad0d..17afd325f03 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -366,7 +366,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { _ => mir::ConstantKind::Ty(const_folded), } } - mir::ConstantKind::Val(_, _) => constant.try_super_fold_with(self)?, + mir::ConstantKind::Val(_, _) | mir::ConstantKind::Unevaluated(..) => { + constant.try_super_fold_with(self)? + } }) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8b15e10ba9c..c8896027ba1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -699,11 +699,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.kind(), c2.kind()) { - if self.infcx.try_unify_abstract_consts( - a.shrink(), - b.shrink(), - obligation.param_env, - ) { + if self.infcx.try_unify_abstract_consts(a, b, obligation.param_env) { return Ok(EvaluatedToOk); } } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 9d3a1a4a031..ff6b5c73386 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -456,7 +456,7 @@ impl<'tcx> WfPredicates<'tcx> { self.out.extend(obligations); let predicate = - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv)) .to_predicate(self.tcx()); let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 3e7a6c3c548..cbc4eab85fd 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2372,10 +2372,10 @@ fn const_evaluatable_predicates_of<'tcx>( let def_id = self.tcx.hir().local_def_id(c.hir_id); let ct = ty::Const::from_anon_const(self.tcx, def_id); if let ty::ConstKind::Unevaluated(uv) = ct.kind() { - assert_eq!(uv.promoted, None); + assert_eq!(uv.promoted, ()); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink())) + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv)) .to_predicate(self.tcx), span, )); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 395f213ca87..070956deca3 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -235,14 +235,13 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => { + assert_eq!(promoted, ()); let mut s = if let Some(def) = def.as_local() { print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did)) } else { inline::print_inlined_const(cx.tcx, def.did) }; - if let Some(promoted) = promoted { - s.push_str(&format!("::{:?}", promoted)) - } + s } _ => { |
