diff options
| author | bors <bors@rust-lang.org> | 2024-06-06 03:41:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-06 03:41:23 +0000 |
| commit | 003a9027927a51de770a1cf22fccade616a5f0e3 (patch) | |
| tree | 520c39f845a120d5f1d72b24444beefa1d3e5935 /compiler | |
| parent | d0ccb5413ee2d9d40b574ad7998ffa866811d3f8 (diff) | |
| parent | 3a6b606ad9e6c9efc83bd9e7ab0025080d052bc0 (diff) | |
Auto merge of #125958 - BoxyUwU:remove_const_ty, r=lcnr
Remove the `ty` field from type system `Const`s Fixes #125556 Fixes #122908 Part of the work on `adt_const_params`/`generic_const_param_types`/`min_generic_const_exprs`/generally making the compiler nicer. cc rust-lang/project-const-generics#44 Please review commit-by-commit otherwise I wasted a lot of time not just squashing this into a giant mess (and also it'll be SO much nicer because theres a lot of fluff changes mixed in with other more careful changes if looking via File Changes --- Why do this? - The `ty` field keeps causing ICEs and weird behaviour due to it either being treated as "part of the const" or it being forgotten about leading to ICEs. - As we move forward with `adt_const_params` and a potential `min_generic_const_exprs` it's going to become more complex to actually lower the correct `Ty<'tcx>` - It muddles the idea behind how we check `Const` arguments have the correct type. By having the `ty` field it may seem like we ought to be relating it when we relate two types, or that its generally important information about the `Const`. - Brings the compiler more in line with `a-mir-formality` as that also tracks the type of type system `Const`s via `ConstArgHasType` bounds in the env instead of on the `Const` itself. - A lot of stuff is a lot nicer when you dont have to pass around the type of a const lol. Everywhere we construct `Const` is now significantly nicer :sweat_smile: See #125671's description for some more information about the `ty` field --- General summary of changes in this PR: - Add `Ty` to `ConstKind::Value` as otherwise there is no way to implement `ConstArgHasType` to ensure that const arguments are correctly typed for the parameter when we stop creating anon consts for all const args. It's also just incredibly difficult/annoying to thread the correct `Ty` around to a bunch of ctfe functions otherwise. - Fully implement `ConstArgHasType` in both the old and new solver. Since it now has no reliance on the `ty` field it serves its originally intended purpose of being able to act as a double check that trait vs impls have correctly typed const parameters. It also will now be able to be responsible for checking types of const arguments to parameters under `min_generic_const_exprs`. - Add `Ty` to `mir::Const::Ty`. I dont have a great understanding of why mir constants are setup like this to be honest. Regardless they need to be able to determine the type of the const and the easiest way to make this happen was to simply store the `Ty` along side the `ty::Const`. Maybe we can do better here in the future but I'd have to spend way more time looking at everywhere we use `mir::Const`. - rustdoc has its own `Const` which also has a `ty` field. It was relatively easy to remove this. --- r? `@lcnr` `@compiler-errors`
Diffstat (limited to 'compiler')
95 files changed, 703 insertions, 873 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 291d2782c32..fcfb297d50a 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -346,7 +346,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } else { let tcx = self.tcx(); let maybe_uneval = match constant.const_ { - Const::Ty(ct) => match ct.kind() { + Const::Ty(_, ct) => match ct.kind() { ty::ConstKind::Unevaluated(_) => { bug!("should not encounter unevaluated Const::Ty here, got {:?}", ct) } @@ -1856,7 +1856,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Operand::Constant(constant) = op { let maybe_uneval = match constant.const_ { - Const::Val(..) | Const::Ty(_) => None, + Const::Val(..) | Const::Ty(_, _) => None, Const::Unevaluated(uv, _) => Some(uv), }; diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index cbd8a4125cd..9863c4a3883 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -193,7 +193,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { types: &mut |_bound_ty: ty::BoundTy| { unreachable!("we only replace regions in nll_relate, not types") }, - consts: &mut |_bound_var: ty::BoundVar, _ty| { + consts: &mut |_bound_var: ty::BoundVar| { unreachable!("we only replace regions in nll_relate, not consts") }, }; @@ -231,7 +231,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { types: &mut |_bound_ty: ty::BoundTy| { unreachable!("we only replace regions in nll_relate, not types") }, - consts: &mut |_bound_var: ty::BoundVar, _ty| { + consts: &mut |_bound_var: ty::BoundVar| { unreachable!("we only replace regions in nll_relate, not consts") }, }; diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index b17f191ce26..65eeaf156d8 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( .expect_const() .eval(fx.tcx, ty::ParamEnv::reveal_all(), span) .unwrap() + .1 .unwrap_branch(); assert_eq!(x.layout(), y.layout()); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 39bbf87bea7..7b1038d5617 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1201,6 +1201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( .expect_const() .eval(tcx, ty::ParamEnv::reveal_all(), span) .unwrap() + .1 .unwrap_branch(); let n = idx.len() as u64; diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 2360cce55a9..c4e5c858240 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -693,41 +693,46 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S ty::ConstKind::Param(param) => { write!(output, "{}", param.name) } - _ => match ct.ty().kind() { - ty::Int(ity) => { - let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all()); - let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; - write!(output, "{val}") - } - ty::Uint(_) => { - let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all()); - write!(output, "{val}") - } - ty::Bool => { - let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap(); - write!(output, "{val}") - } - _ => { - // If we cannot evaluate the constant to a known type, we fall back - // to emitting a stable hash value of the constant. This isn't very pretty - // but we get a deterministic, virtually unique value for the constant. - // - // Let's only emit 64 bits of the hash value. That should be plenty for - // avoiding collisions and will make the emitted type names shorter. - let hash_short = tcx.with_stable_hashing_context(|mut hcx| { - let mut hasher = StableHasher::new(); - let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap(); - hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher)); - hasher.finish::<Hash64>() - }); - - if cpp_like_debuginfo(tcx) { - write!(output, "CONST${hash_short:x}") - } else { - write!(output, "{{CONST#{hash_short:x}}}") + ty::ConstKind::Value(ty, _) => { + match ty.kind() { + ty::Int(ity) => { + // FIXME: directly extract the bits from a valtree instead of evaluating an + // alreay evaluated `Const` in order to get the bits. + let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all()); + let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; + write!(output, "{val}") + } + ty::Uint(_) => { + let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all()); + write!(output, "{val}") + } + ty::Bool => { + let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap(); + write!(output, "{val}") + } + _ => { + // If we cannot evaluate the constant to a known type, we fall back + // to emitting a stable hash value of the constant. This isn't very pretty + // but we get a deterministic, virtually unique value for the constant. + // + // Let's only emit 64 bits of the hash value. That should be plenty for + // avoiding collisions and will make the emitted type names shorter. + let hash_short = tcx.with_stable_hashing_context(|mut hcx| { + let mut hasher = StableHasher::new(); + let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap(); + hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher)); + hasher.finish::<Hash64>() + }); + + if cpp_like_debuginfo(tcx) { + write!(output, "CONST${hash_short:x}") + } else { + write!(output, "{{CONST#{hash_short:x}}}") + } } } - }, + } + _ => bug!("Invalid `Const` during codegen: {:?}", ct), } .unwrap(); } diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index dba5fbefd8a..822f5c2c44a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -40,10 +40,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> { let uv = match self.monomorphize(constant.const_) { mir::Const::Unevaluated(uv, _) => uv.shrink(), - mir::Const::Ty(c) => match c.kind() { + mir::Const::Ty(_, c) => match c.kind() { // A constant that came from a const generic but was then used as an argument to old-style // simd_shuffle (passing as argument instead of as a generic param). - rustc_type_ir::ConstKind::Value(valtree) => return Ok(Some(valtree)), + rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Some(valtree)), other => span_bug!(constant.span, "{other:#?}"), }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 5949444e599..9fd7219499b 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -357,15 +357,15 @@ where // Check the qualifs of the value of `const` items. let uneval = match constant.const_ { - Const::Ty(ct) + Const::Ty(_, ct) if matches!( ct.kind(), - ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_) + ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _) ) => { None } - Const::Ty(c) => { + Const::Ty(_, c) => { bug!("expected ConstKind::Param or ConstKind::Value here, found {:?}", c) } Const::Unevaluated(uv, _) => Some(uv), diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 74dcd672578..82b57cdd106 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2198,9 +2198,6 @@ fn param_env_with_gat_bounds<'tcx>( tcx, ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1), - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), ) .into() } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index d84dcb78ad2..092d2d304c3 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -396,16 +396,8 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { Ty::new_error_with_message(self.tcx(), span, "bad placeholder type") } - fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { - let ty = self.tcx.fold_regions(ty, |r, _| match *r { - rustc_type_ir::RegionKind::ReStatic => r, - - // This is never reached in practice. If it ever is reached, - // `ReErased` should be changed to `ReStatic`, and any other region - // left alone. - r => bug!("unexpected region: {r:?}"), - }); - ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant") + fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { + ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant") } fn probe_ty_param_bounds( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 913fae6b5b6..40204961e9c 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -196,7 +196,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen .type_of(param.def_id.to_def_id()) .no_bound_vars() .expect("const parameters cannot be generic"); - let ct = icx.lowerer().lower_const_param(param.hir_id, ct_ty); + let ct = icx.lowerer().lower_const_param(param.hir_id); predicates .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span)); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 73ce577907e..7f6f57907c2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -368,11 +368,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }, ) }); - let ty = tcx - .type_of(param.def_id) - .no_bound_vars() - .expect("ct params cannot have early bound vars"); - ty::Const::new_error(tcx, guar, ty).into() + ty::Const::new_error(tcx, guar).into() } }; num_bound_vars += 1; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 9b8edbc10ad..7ec64f1feda 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -111,12 +111,7 @@ pub trait HirTyLowerer<'tcx> { fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>; /// Returns the const to use when a const is omitted. - fn ct_infer( - &self, - ty: Ty<'tcx>, - param: Option<&ty::GenericParamDef>, - span: Span, - ) -> Const<'tcx>; + fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>; /// Probe bounds in scope where the bounded type coincides with the given type parameter. /// @@ -439,7 +434,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn provided_kind( &mut self, - preceding_args: &[ty::GenericArg<'tcx>], + _preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -447,7 +442,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Err(incorrect) = self.incorrect_args { if incorrect.invalid_args.contains(&(param.index as usize)) { - return param.to_error(tcx, preceding_args); + return param.to_error(tcx); } } @@ -487,12 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::Const::from_anon_const(tcx, did).into() } (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { - let ty = tcx - .at(self.span) - .type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"); - self.lowerer.ct_infer(ty, Some(param), inf.span).into() + self.lowerer.ct_infer(Some(param), inf.span).into() } (kind, arg) => span_bug!( self.span, @@ -511,7 +501,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Err(incorrect) = self.incorrect_args { if incorrect.invalid_args.contains(&(param.index as usize)) { - return param.to_error(tcx, preceding_args); + return param.to_error(tcx); } } match param.kind { @@ -548,7 +538,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .no_bound_vars() .expect("const parameter types cannot be generic"); if let Err(guar) = ty.error_reported() { - return ty::Const::new_error(tcx, guar, ty).into(); + return ty::Const::new_error(tcx, guar).into(); } // FIXME(effects) see if we should special case effect params here if !infer_args && has_default { @@ -557,10 +547,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .into() } else { if infer_args { - self.lowerer.ct_infer(ty, Some(param), self.span).into() + self.lowerer.ct_infer(Some(param), self.span).into() } else { // We've already errored above about the mismatch. - ty::Const::new_misc_error(tcx, ty).into() + ty::Const::new_misc_error(tcx).into() } } } @@ -1908,7 +1898,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// Early-bound const parameters get lowered to [`ty::ConstKind::Param`] /// and late-bound ones to [`ty::ConstKind::Bound`]. - pub(crate) fn lower_const_param(&self, hir_id: HirId, param_ty: Ty<'tcx>) -> Const<'tcx> { + pub(crate) fn lower_const_param(&self, hir_id: HirId) -> Const<'tcx> { let tcx = self.tcx(); match tcx.named_bound_var(hir_id) { Some(rbv::ResolvedArg::EarlyBound(def_id)) => { @@ -1918,12 +1908,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; let name = tcx.item_name(def_id); - ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty) + ty::Const::new_param(tcx, ty::ParamConst::new(index, name)) } Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => { - ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index), param_ty) + ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index)) } - Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar, param_ty), + Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar), arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id), } } @@ -2139,7 +2129,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } hir::TyKind::Array(ty, length) => { let length = match length { - hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span), + hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span), hir::ArrayLen::Body(constant) => { ty::Const::from_anon_const(tcx, constant.def_id) } @@ -2170,17 +2160,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } _ => (expr, None), }; - let c = match &expr.kind { + let (c, c_ty) = match &expr.kind { hir::ExprKind::Lit(lit) => { let lit_input = LitToConstInput { lit: &lit.node, ty, neg: neg.is_some() }; - match tcx.lit_to_const(lit_input) { + let ct = match tcx.lit_to_const(lit_input) { Ok(c) => c, Err(LitToConstError::Reported(err)) => { - ty::Const::new_error(tcx, err, ty) + ty::Const::new_error(tcx, err) } Err(LitToConstError::TypeError) => todo!(), - } + }; + (ct, ty) } hir::ExprKind::Path(hir::QPath::Resolved( @@ -2198,19 +2189,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .type_of(def_id) .no_bound_vars() .expect("const parameter types cannot be generic"); - self.lower_const_param(expr.hir_id, ty) + let ct = self.lower_const_param(expr.hir_id); + (ct, ty) } _ => { let err = tcx .dcx() .emit_err(crate::errors::NonConstRange { span: expr.span }); - ty::Const::new_error(tcx, err, ty) + (ty::Const::new_error(tcx, err), Ty::new_error(tcx, err)) } }; - self.record_ty(expr.hir_id, c.ty(), expr.span); + self.record_ty(expr.hir_id, c_ty, expr.span); if let Some((id, span)) = neg { - self.record_ty(id, c.ty(), span); + self.record_ty(id, c_ty, span); } c }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index b9c5ae0c65b..34924f09d09 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -143,9 +143,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `trait_object_dummy_self`, so check for that. let references_self = match pred.skip_binder().term.unpack() { ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()), - ty::TermKind::Const(c) => { - c.ty().walk().any(|arg| arg == dummy_self.into()) - } + // FIXME(associated_const_equality): We should walk the const instead of not doing anything + ty::TermKind::Const(_) => false, }; // If the projection output contains `Self`, force the user to diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index fa147f9bfcf..5d30b2a71e0 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -350,7 +350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lt_op: |_| self.tcx.lifetimes.re_erased, ct_op: |ct| { if let ty::ConstKind::Infer(_) = ct.kind() { - self.next_const_var(ct.ty(), DUMMY_SP) + self.next_const_var(DUMMY_SP) } else { ct } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 157b0be6164..85c6d4dc12c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -436,7 +436,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> { match length { - hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span), + hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span), hir::ArrayLen::Body(anon_const) => { let span = self.tcx.def_span(anon_const.def_id); let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id); @@ -1292,20 +1292,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &GenericParamDefKind::Const { has_default, is_host_effect }, GenericArg::Infer(inf), ) => { - let tcx = self.fcx.tcx(); - if has_default && is_host_effect { self.fcx.var_for_effect(param) } else { - self.fcx - .ct_infer( - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), - Some(param), - inf.span, - ) - .into() + self.fcx.ct_infer(Some(param), inf.span).into() } } _ => unreachable!(), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index b9ff348c42f..f02b0f95390 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -237,12 +237,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { } } - fn ct_infer( - &self, - ty: Ty<'tcx>, - param: Option<&ty::GenericParamDef>, - span: Span, - ) -> Const<'tcx> { + fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { // FIXME ideally this shouldn't use unwrap match param { Some( @@ -252,7 +247,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { }, ) => self.var_for_effect(param).as_const().unwrap(), Some(param) => self.var_for_def(span, param).as_const().unwrap(), - None => self.next_const_var(ty, span), + None => self.next_const_var(span), } } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 949b9241005..3c9a49e91a3 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -406,16 +406,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.cfcx.ty_infer(Some(param), inf.span).into() } (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { - let tcx = self.cfcx.tcx(); - self.cfcx - .ct_infer( - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), - Some(param), - inf.span, - ) - .into() + self.cfcx.ct_infer(Some(param), inf.span).into() } (kind, arg) => { bug!("mismatched method arg kind {kind:?} in turbofish: {arg:?}") diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index b3947e142b2..c1e14f7fb75 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2096,9 +2096,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)) .into(), GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(), - GenericArgKind::Const(arg) => { - self.next_const_var(arg.ty(), DUMMY_SP).into() - } + GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(), } } else { arg diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 93fb83fb3e4..ba3233956b1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2409,7 +2409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_len: u64, ) -> (Option<Ty<'tcx>>, Ty<'tcx>) { let len = match len.eval(self.tcx, self.param_env, span) { - Ok(val) => val + // FIXME(BoxyUwU): Assert the `Ty` is a `usize`? + Ok((_, val)) => val .try_to_scalar() .and_then(|scalar| scalar.try_to_int().ok()) .and_then(|int| int.try_to_target_usize(self.tcx).ok()), diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index e337105f011..8727c0f87dc 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -863,7 +863,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { self.handle_term(ct, ty::Const::outer_exclusive_binder, |tcx, guar| { - ty::Const::new_error(tcx, guar, ct.ty()) + ty::Const::new_error(tcx, guar) }) .super_fold_with(self) } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 27b06c4b73e..bc2592b43f3 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -462,7 +462,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { // any equated inference vars correctly! let root_vid = self.infcx.unwrap().root_const_var(vid); if root_vid != vid { - ct = ty::Const::new_var(self.tcx, root_vid, ct.ty()); + ct = ty::Const::new_var(self.tcx, root_vid); vid = root_vid; } @@ -481,7 +481,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { ui = ty::UniverseIndex::ROOT; } return self.canonicalize_const_var( - CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty()) }, + CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) }, ct, ); } @@ -510,9 +510,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { } ty::ConstKind::Placeholder(placeholder) => { return self.canonicalize_const_var( - CanonicalVarInfo { - kind: CanonicalVarKind::PlaceholderConst(placeholder, ct.ty()), - }, + CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) }, ct, ); } @@ -719,9 +717,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { CanonicalVarKind::Region(u) => { CanonicalVarKind::Region(reverse_universe_map[&u]) } - CanonicalVarKind::Const(u, t) => { - CanonicalVarKind::Const(reverse_universe_map[&u], t) - } + CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]), CanonicalVarKind::PlaceholderTy(placeholder) => { CanonicalVarKind::PlaceholderTy(ty::Placeholder { universe: reverse_universe_map[&placeholder.universe], @@ -734,14 +730,11 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { ..placeholder }) } - CanonicalVarKind::PlaceholderConst(placeholder, t) => { - CanonicalVarKind::PlaceholderConst( - ty::Placeholder { - universe: reverse_universe_map[&placeholder.universe], - ..placeholder - }, - t, - ) + CanonicalVarKind::PlaceholderConst(placeholder) => { + CanonicalVarKind::PlaceholderConst(ty::Placeholder { + universe: reverse_universe_map[&placeholder.universe], + ..placeholder + }) } }, }) @@ -806,6 +799,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve_const(const_var)) ); let var = self.canonical_var(info, const_var.into()); - ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty())) + ty::Const::new_bound(self.tcx, self.binder_index, var) } } diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index de0e15ef3de..153de3d4c09 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -70,7 +70,7 @@ where GenericArgKind::Type(ty) => ty, r => bug!("{:?} is a type but value is {:?}", bound_ty, r), }, - consts: &mut |bound_ct: ty::BoundVar, _| match var_values[bound_ct].unpack() { + consts: &mut |bound_ct: ty::BoundVar| match var_values[bound_ct].unpack() { GenericArgKind::Const(ct) => ct, c => bug!("{:?} is a const but value is {:?}", bound_ct, c), }, diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 1abb8086d41..8ad4f7926ca 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -143,8 +143,8 @@ impl<'tcx> InferCtxt<'tcx> { ty::Region::new_placeholder(self.tcx, placeholder_mapped).into() } - CanonicalVarKind::Const(ui, ty) => { - self.next_const_var_in_universe(ty, span, universe_map(ui)).into() + CanonicalVarKind::Const(ui) => { + self.next_const_var_in_universe(span, universe_map(ui)).into() } CanonicalVarKind::Effect => { let vid = self @@ -153,13 +153,12 @@ impl<'tcx> InferCtxt<'tcx> { .effect_unification_table() .new_key(EffectVarValue::Unknown) .vid; - ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool) - .into() + ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid)).into() } - CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }, ty) => { + CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound }; - ty::Const::new_placeholder(self.tcx, placeholder_mapped, ty).into() + ty::Const::new_placeholder(self.tcx, placeholder_mapped).into() } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index fb8c843f309..cb0e13652e8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -543,9 +543,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { match arg.unpack() { GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(), - GenericArgKind::Const(arg) => { - self.next_const_var(arg.ty(), DUMMY_SP).into() - } + GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(), } })) .unwrap(); diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index a3c8d5f4251..4bb59bd9037 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -79,7 +79,6 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { &mut self, input: Result<ty::Const<'tcx>, ty::InferConst>, freshener: F, - ty: Ty<'tcx>, ) -> ty::Const<'tcx> where F: FnOnce(u32) -> ty::InferConst, @@ -91,7 +90,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { Entry::Vacant(entry) => { let index = self.const_freshen_count; self.const_freshen_count += 1; - let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty); + let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index)); entry.insert(ct); ct } @@ -149,7 +148,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> { ty::InferConst::Var(inner.const_unification_table().find(v).vid) }); drop(inner); - self.freshen_const(input, ty::InferConst::Fresh, ct.ty()) + self.freshen_const(input, ty::InferConst::Fresh) } ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => { let mut inner = self.infcx.inner.borrow_mut(); @@ -158,7 +157,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> { ty::InferConst::EffectVar(inner.effect_unification_table().find(v).vid) }); drop(inner); - self.freshen_const(input, ty::InferConst::Fresh, ct.ty()) + self.freshen_const(input, ty::InferConst::Fresh) } ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => { if i >= self.const_freshen_count { @@ -177,7 +176,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> { } ty::ConstKind::Param(_) - | ty::ConstKind::Value(_) + | ty::ConstKind::Value(_, _) | ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) | ty::ConstKind::Error(_) => ct.super_fold_with(self), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e9a4cc3e04b..4476611d9c8 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -392,18 +392,18 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> { self.opportunistic_resolve_float_var(vid) } - fn opportunistic_resolve_ct_var(&self, vid: ConstVid, ty: Ty<'tcx>) -> ty::Const<'tcx> { + fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> ty::Const<'tcx> { match self.probe_const_var(vid) { Ok(ct) => ct, - Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid), ty), + Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)), } } - fn opportunistic_resolve_effect_var(&self, vid: EffectVid, ty: Ty<'tcx>) -> ty::Const<'tcx> { + fn opportunistic_resolve_effect_var(&self, vid: EffectVid) -> ty::Const<'tcx> { match self.probe_effect_var(vid) { Some(ct) => ct, None => { - ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid)), ty) + ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid))) } } } @@ -832,9 +832,7 @@ impl<'tcx> InferCtxt<'tcx> { (0..table.len()) .map(|i| ty::EffectVid::from_usize(i)) .filter(|&vid| table.probe_value(vid).is_unknown()) - .map(|v| { - ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool) - }) + .map(|v| ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v))) .collect() } @@ -993,27 +991,22 @@ impl<'tcx> InferCtxt<'tcx> { Ty::new_var(self.tcx, vid) } - pub fn next_const_var(&self, ty: Ty<'tcx>, span: Span) -> ty::Const<'tcx> { - self.next_const_var_with_origin(ty, ConstVariableOrigin { span, param_def_id: None }) + pub fn next_const_var(&self, span: Span) -> ty::Const<'tcx> { + self.next_const_var_with_origin(ConstVariableOrigin { span, param_def_id: None }) } - pub fn next_const_var_with_origin( - &self, - ty: Ty<'tcx>, - origin: ConstVariableOrigin, - ) -> ty::Const<'tcx> { + pub fn next_const_var_with_origin(&self, origin: ConstVariableOrigin) -> ty::Const<'tcx> { let vid = self .inner .borrow_mut() .const_unification_table() .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() }) .vid; - ty::Const::new_var(self.tcx, vid, ty) + ty::Const::new_var(self.tcx, vid) } pub fn next_const_var_in_universe( &self, - ty: Ty<'tcx>, span: Span, universe: ty::UniverseIndex, ) -> ty::Const<'tcx> { @@ -1024,7 +1017,7 @@ impl<'tcx> InferCtxt<'tcx> { .const_unification_table() .new_key(ConstVariableValue::Unknown { origin, universe }) .vid; - ty::Const::new_var(self.tcx, vid, ty) + ty::Const::new_var(self.tcx, vid) } pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid { @@ -1135,15 +1128,7 @@ impl<'tcx> InferCtxt<'tcx> { .const_unification_table() .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() }) .vid; - ty::Const::new_var( - self.tcx, - const_var_id, - self.tcx - .type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), - ) - .into() + ty::Const::new_var(self.tcx, const_var_id).into() } } } @@ -1157,7 +1142,7 @@ impl<'tcx> InferCtxt<'tcx> { .no_bound_vars() .expect("const parameter types cannot be generic"); debug_assert_eq!(self.tcx.types.bool, ty); - ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid), ty).into() + ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid)).into() } /// Given a set of generics defined on a type or impl, returns the generic parameters mapping each @@ -1314,7 +1299,7 @@ impl<'tcx> InferCtxt<'tcx> { | ty::ConstKind::Bound(_, _) | ty::ConstKind::Placeholder(_) | ty::ConstKind::Unevaluated(_) - | ty::ConstKind::Value(_) + | ty::ConstKind::Value(_, _) | ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => ct, } @@ -1469,10 +1454,10 @@ impl<'tcx> InferCtxt<'tcx> { .or_insert_with(|| self.infcx.next_ty_var(self.span).into()) .expect_ty() } - fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> { + fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> { self.map .entry(bv) - .or_insert_with(|| self.infcx.next_const_var(ty, self.span).into()) + .or_insert_with(|| self.infcx.next_const_var(self.span).into()) .expect_const() } } @@ -1526,11 +1511,14 @@ impl<'tcx> InferCtxt<'tcx> { &self, param_env: ty::ParamEnv<'tcx>, unevaluated: ty::UnevaluatedConst<'tcx>, - ty: Ty<'tcx>, span: Span, ) -> Result<ty::Const<'tcx>, ErrorHandled> { match self.const_eval_resolve(param_env, unevaluated, span) { - Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, ty)), + Ok(Some(val)) => Ok(ty::Const::new_value( + self.tcx, + val, + self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args), + )), Ok(None) => { let tcx = self.tcx; let def_id = unevaluated.def; @@ -1964,11 +1952,6 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>( fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { if let ty::ConstKind::Infer(_) = c.kind() { - let ty = c.ty(); - // If the type references param or infer then ICE ICE ICE - if ty.has_non_region_param() || ty.has_non_region_infer() { - bug!("const `{c}`'s type should not reference params or types"); - } ty::Const::new_placeholder( self.tcx, ty::PlaceholderConst { @@ -1979,7 +1962,6 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>( idx }), }, - ty, ) } else { c.super_fold_with(self) diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index aaea3b4820b..225c126fcf8 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -653,7 +653,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { { variable_table.union(vid, new_var_id); } - Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty())) + Ok(ty::Const::new_var(self.tcx(), new_var_id)) } } } @@ -671,11 +671,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { args, args, )?; - Ok(ty::Const::new_unevaluated( - self.tcx(), - ty::UnevaluatedConst { def, args }, - c.ty(), - )) + Ok(ty::Const::new_unevaluated(self.tcx(), ty::UnevaluatedConst { def, args })) } ty::ConstKind::Placeholder(placeholder) => { if self.for_universe.can_name(placeholder.universe) { diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs index 70ed7cf9af1..d3001eb5838 100644 --- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs +++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs @@ -43,11 +43,10 @@ impl<'tcx> InferCtxt<'tcx> { ty::PlaceholderType { universe: next_universe, bound: bound_ty }, ) }, - consts: &mut |bound_var: ty::BoundVar, ty| { + consts: &mut |bound_var: ty::BoundVar| { ty::Const::new_placeholder( self.tcx, ty::PlaceholderConst { universe: next_universe, bound: bound_var }, - ty, ) }, }; diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 4408251c99d..a086c82c92e 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -244,7 +244,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> { // Recreate it with a fresh variable here. let idx = vid.index() - self.const_vars.0.start.index(); let origin = self.const_vars.1[idx]; - self.infcx.next_const_var_with_origin(ct.ty(), origin) + self.infcx.next_const_var_with_origin(origin) } else { ct } diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index e107c2c12bd..cc8979dd990 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -204,7 +204,9 @@ pub enum Const<'tcx> { /// Any way of turning `ty::Const` into `ConstValue` should go through `valtree_to_const_val`; /// this ensures that we consistently produce "clean" values without data in the padding or /// anything like that. - Ty(ty::Const<'tcx>), + /// + /// FIXME(BoxyUwU): We should remove this `Ty` and look up the type for params via `ParamEnv` + Ty(Ty<'tcx>, ty::Const<'tcx>), /// An unevaluated mir constant which is not part of the type system. /// @@ -237,7 +239,15 @@ impl<'tcx> Const<'tcx> { #[inline(always)] pub fn ty(&self) -> Ty<'tcx> { match self { - Const::Ty(c) => c.ty(), + Const::Ty(ty, ct) => { + match ct.kind() { + // Dont use the outter ty as on invalid code we can wind up with them not being the same. + // this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir + // was originally `({N: usize} + 1_usize)` under `generic_const_exprs`. + ty::ConstKind::Value(ty, _) => ty, + _ => *ty, + } + } Const::Val(_, ty) | Const::Unevaluated(_, ty) => *ty, } } @@ -247,8 +257,8 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn is_required_const(&self) -> bool { match self { - Const::Ty(c) => match c.kind() { - ty::ConstKind::Value(_) => false, // already a value, cannot error + Const::Ty(_, c) => match c.kind() { + ty::ConstKind::Value(_, _) => false, // already a value, cannot error _ => true, }, Const::Val(..) => false, // already a value, cannot error @@ -259,8 +269,8 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn try_to_scalar(self) -> Option<Scalar> { match self { - Const::Ty(c) => match c.kind() { - ty::ConstKind::Value(valtree) if c.ty().is_primitive() => { + Const::Ty(_, c) => match c.kind() { + ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => { // A valtree of a type where leaves directly represent the scalar const value. // Just checking whether it is a leaf is insufficient as e.g. references are leafs // but the leaf value is the value they point to, not the reference itself! @@ -278,8 +288,8 @@ impl<'tcx> Const<'tcx> { // This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster. match self { Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x), - Const::Ty(c) => match c.kind() { - ty::ConstKind::Value(valtree) if c.ty().is_primitive() => { + Const::Ty(_, c) => match c.kind() { + ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => { Some(valtree.unwrap_leaf()) } _ => None, @@ -306,11 +316,11 @@ impl<'tcx> Const<'tcx> { span: Span, ) -> Result<ConstValue<'tcx>, ErrorHandled> { match self { - Const::Ty(c) => { + Const::Ty(_, c) => { // We want to consistently have a "clean" value for type system constants (i.e., no // data hidden in the padding), so we always go through a valtree here. - let val = c.eval(tcx, param_env, span)?; - Ok(tcx.valtree_to_const_val((self.ty(), val))) + let (ty, val) = c.eval(tcx, param_env, span)?; + Ok(tcx.valtree_to_const_val((ty, val))) } Const::Unevaluated(uneval, _) => { // FIXME: We might want to have a `try_eval`-like function on `Unevaluated` @@ -326,7 +336,7 @@ impl<'tcx> Const<'tcx> { match self.eval(tcx, param_env, DUMMY_SP) { Ok(val) => Self::Val(val, self.ty()), Err(ErrorHandled::Reported(guar, _span)) => { - Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty())) + Self::Ty(Ty::new_error(tcx, guar.into()), ty::Const::new_error(tcx, guar.into())) } Err(ErrorHandled::TooGeneric(_span)) => self, } @@ -338,15 +348,16 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option<Scalar> { - match self { - Const::Ty(c) if c.ty().is_primitive() => { - // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that - // are valtree leaves, and *not* on references. (References should return the - // pointer here, which valtrees don't represent.) - let val = c.eval(tcx, param_env, DUMMY_SP).ok()?; - Some(val.unwrap_leaf().into()) - } - _ => self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar(), + if let Const::Ty(_, c) = self + && let ty::ConstKind::Value(ty, val) = c.kind() + && ty.is_primitive() + { + // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that + // are valtree leaves, and *not* on references. (References should return the + // pointer here, which valtrees don't represent.) + Some(val.unwrap_leaf().into()) + } else { + self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar() } } @@ -439,14 +450,14 @@ impl<'tcx> Const<'tcx> { Self::Val(val, ty) } - pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + pub fn from_ty_const(c: ty::Const<'tcx>, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Self { match c.kind() { - ty::ConstKind::Value(valtree) => { + ty::ConstKind::Value(ty, valtree) => { // Make sure that if `c` is normalized, then the return value is normalized. - let const_val = tcx.valtree_to_const_val((c.ty(), valtree)); - Self::Val(const_val, c.ty()) + let const_val = tcx.valtree_to_const_val((ty, valtree)); + Self::Val(const_val, ty) } - _ => Self::Ty(c), + _ => Self::Ty(ty, c), } } @@ -458,12 +469,12 @@ impl<'tcx> Const<'tcx> { // - valtrees purposefully generate new allocations // - ConstValue::Slice also generate new allocations match self { - Const::Ty(c) => match c.kind() { + Const::Ty(_, c) => match c.kind() { ty::ConstKind::Param(..) => true, // A valtree may be a reference. Valtree references correspond to a // different allocation each time they are evaluated. Valtrees for primitive // types are fine though. - ty::ConstKind::Value(_) => c.ty().is_primitive(), + ty::ConstKind::Value(ty, _) => ty.is_primitive(), ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) => false, // This can happen if evaluation of a constant failed. The result does not matter // much since compilation is doomed. @@ -517,7 +528,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { impl<'tcx> Display for Const<'tcx> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { match *self { - Const::Ty(c) => pretty_print_const(c, fmt, true), + Const::Ty(_, c) => pretty_print_const(c, fmt, true), Const::Val(val, ty) => pretty_print_const_value(val, ty, fmt), // FIXME(valtrees): Correctly print mir constants. Const::Unevaluated(c, _ty) => { diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f1c79c0b039..c91b67297ee 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1313,12 +1313,12 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { }; let val = match const_ { - Const::Ty(ct) => match ct.kind() { + Const::Ty(_, ct) => match ct.kind() { ty::ConstKind::Param(p) => format!("ty::Param({p})"), ty::ConstKind::Unevaluated(uv) => { format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,) } - ty::ConstKind::Value(val) => format!("ty::Valtree({})", fmt_valtree(&val)), + ty::ConstKind::Value(_, val) => format!("ty::Valtree({})", fmt_valtree(&val)), // No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`. ty::ConstKind::Error(_) => "Error".to_string(), // These variants shouldn't exist in the MIR. @@ -1417,7 +1417,7 @@ pub fn write_allocations<'tcx>( impl<'tcx> Visitor<'tcx> for CollectAllocIds { fn visit_constant(&mut self, c: &ConstOperand<'tcx>, _: Location) { match c.const_ { - Const::Ty(_) | Const::Unevaluated(..) => {} + Const::Ty(_, _) | Const::Unevaluated(..) => {} Const::Val(val, _) => { self.0.extend(alloc_ids_from_const_val(val)); } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 8901fd42d93..f553b417294 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -895,7 +895,7 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); match const_ { - Const::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location), + Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location), Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 62e71c4db11..63678ab659d 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -616,6 +616,8 @@ pub enum SelectionError<'tcx> { /// We can thus not know whether the hidden type implements an auto trait, so /// we should not presume anything about it. OpaqueTypeAutoTraitLeakageUnknown(DefId), + /// Error for a `ConstArgHasType` goal + ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> }, } #[derive(Clone, Debug, TypeVisitable)] diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 7fb5e9aadae..254e1b54481 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -53,7 +53,7 @@ impl<'tcx> TyCtxt<'tcx> { fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> { let ct = match c.kind() { ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) { - Err(e) => ty::Const::new_error(self.tcx, e, c.ty()), + Err(e) => ty::Const::new_error(self.tcx, e), Ok(Some(bac)) => { let args = self.tcx.erase_regions(uv.args); let bac = bac.instantiate(self.tcx, args); diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 07652b47929..33f564e9b59 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -350,8 +350,8 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Const<'tcx> { fn decode(decoder: &mut D) -> Self { - let consts: ty::ConstData<'tcx> = Decodable::decode(decoder); - decoder.interner().mk_ct_from_kind(consts.kind, consts.ty) + let kind: ty::ConstKind<'tcx> = Decodable::decode(decoder); + decoder.interner().mk_ct_from_kind(kind) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 384a4e7009d..dc13cc5437d 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -6,7 +6,7 @@ use rustc_error_messages::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; +use rustc_macros::HashStable; use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; use tracing::{debug, instrument}; @@ -24,12 +24,11 @@ pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>; pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>; #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(ConstKind<'_>, 24); +rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); -/// Use this rather than `ConstData`, whenever possible. #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] #[rustc_pass_by_value] -pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>); +pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstKind<'tcx>>>); impl<'tcx> rustc_type_ir::inherent::IntoKind for Const<'tcx> { type Kind = ConstKind<'tcx>; @@ -49,26 +48,11 @@ impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> { } } -/// Typed constant value. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[derive(HashStable, TyEncodable, TyDecodable)] -pub struct ConstData<'tcx> { - pub ty: Ty<'tcx>, - pub kind: ConstKind<'tcx>, -} - -#[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(ConstData<'_>, 32); - impl<'tcx> Const<'tcx> { #[inline] - pub fn ty(self) -> Ty<'tcx> { - self.0.ty - } - - #[inline] pub fn kind(self) -> ConstKind<'tcx> { - self.0.kind + let a: &ConstKind<'tcx> = self.0.0; + *a } // FIXME(compiler-errors): Think about removing this. @@ -84,28 +68,28 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn new(tcx: TyCtxt<'tcx>, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - tcx.mk_ct_from_kind(kind, ty) + pub fn new(tcx: TyCtxt<'tcx>, kind: ty::ConstKind<'tcx>) -> Const<'tcx> { + tcx.mk_ct_from_kind(kind) } #[inline] - pub fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamConst, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Param(param), ty) + pub fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamConst) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Param(param)) } #[inline] - pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Var(infer)), ty) + pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Var(infer))) } #[inline] - pub fn new_fresh(tcx: TyCtxt<'tcx>, fresh: u32, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Fresh(fresh)), ty) + pub fn new_fresh(tcx: TyCtxt<'tcx>, fresh: u32) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Fresh(fresh))) } #[inline] - pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Infer(infer), ty) + pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Infer(infer)) } #[inline] @@ -113,50 +97,40 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar, - ty: Ty<'tcx>, ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Bound(debruijn, var), ty) + Const::new(tcx, ty::ConstKind::Bound(debruijn, var)) } #[inline] - pub fn new_placeholder( - tcx: TyCtxt<'tcx>, - placeholder: ty::PlaceholderConst, - ty: Ty<'tcx>, - ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Placeholder(placeholder), ty) + pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Placeholder(placeholder)) } #[inline] - pub fn new_unevaluated( - tcx: TyCtxt<'tcx>, - uv: ty::UnevaluatedConst<'tcx>, - ty: Ty<'tcx>, - ) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Unevaluated(uv), ty) + pub fn new_unevaluated(tcx: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Unevaluated(uv)) } #[inline] pub fn new_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Value(val), ty) + Const::new(tcx, ty::ConstKind::Value(ty, val)) } #[inline] - pub fn new_expr(tcx: TyCtxt<'tcx>, expr: ty::Expr<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Expr(expr), ty) + pub fn new_expr(tcx: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Expr(expr)) } #[inline] - pub fn new_error(tcx: TyCtxt<'tcx>, e: ty::ErrorGuaranteed, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Error(e), ty) + pub fn new_error(tcx: TyCtxt<'tcx>, e: ty::ErrorGuaranteed) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Error(e)) } /// Like [Ty::new_error] but for constants. #[track_caller] - pub fn new_misc_error(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { + pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Const<'tcx> { Const::new_error_with_message( tcx, - ty, DUMMY_SP, "ty::ConstKind::Error constructed but no error reported", ) @@ -166,52 +140,33 @@ impl<'tcx> Const<'tcx> { #[track_caller] pub fn new_error_with_message<S: Into<MultiSpan>>( tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, span: S, msg: &'static str, ) -> Const<'tcx> { let reported = tcx.dcx().span_delayed_bug(span, msg); - Const::new_error(tcx, reported, ty) + Const::new_error(tcx, reported) } } impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> { - fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Self { - Const::new_infer(tcx, infer, ty) + fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self { + Const::new_infer(tcx, infer) } - fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid, ty: Ty<'tcx>) -> Self { - Const::new_var(tcx, vid, ty) + fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid) -> Self { + Const::new_var(tcx, vid) } - fn new_bound( - interner: TyCtxt<'tcx>, - debruijn: ty::DebruijnIndex, - var: ty::BoundVar, - ty: Ty<'tcx>, - ) -> Self { - Const::new_bound(interner, debruijn, var, ty) + fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self { + Const::new_bound(interner, debruijn, var) } - fn new_anon_bound( - tcx: TyCtxt<'tcx>, - debruijn: ty::DebruijnIndex, - var: ty::BoundVar, - ty: Ty<'tcx>, - ) -> Self { - Const::new_bound(tcx, debruijn, var, ty) - } - - fn new_unevaluated( - interner: TyCtxt<'tcx>, - uv: ty::UnevaluatedConst<'tcx>, - ty: Ty<'tcx>, - ) -> Self { - Const::new_unevaluated(interner, uv, ty) + fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self { + Const::new_bound(tcx, debruijn, var) } - fn ty(self) -> Ty<'tcx> { - self.ty() + fn new_unevaluated(interner: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Self { + Const::new_unevaluated(interner, uv) } } @@ -241,7 +196,6 @@ impl<'tcx> Const<'tcx> { def: def.to_def_id(), args: GenericArgs::identity_for_item(tcx, def.to_def_id()), }, - ty, ), } } @@ -293,9 +247,6 @@ impl<'tcx> Const<'tcx> { _, &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. }, )) => { - // Use the type from the param's definition, since we can resolve it, - // not the expected parameter type from WithOptConstParam. - let param_ty = tcx.type_of(def_id).instantiate_identity(); match tcx.named_bound_var(expr.hir_id) { Some(rbv::ResolvedArg::EarlyBound(_)) => { // Find the name and index of the const parameter by indexing the generics of @@ -304,19 +255,12 @@ impl<'tcx> Const<'tcx> { let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; let name = tcx.item_name(def_id); - Some(ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty)) + Some(ty::Const::new_param(tcx, ty::ParamConst::new(index, name))) } Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => { - Some(ty::Const::new_bound( - tcx, - debruijn, - ty::BoundVar::from_u32(index), - param_ty, - )) - } - Some(rbv::ResolvedArg::Error(guar)) => { - Some(ty::Const::new_error(tcx, guar, param_ty)) + Some(ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))) } + Some(rbv::ResolvedArg::Error(guar)) => Some(ty::Const::new_error(tcx, guar)), arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id), } } @@ -363,7 +307,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, span: Span, - ) -> Result<ValTree<'tcx>, ErrorHandled> { + ) -> Result<(Ty<'tcx>, ValTree<'tcx>), ErrorHandled> { assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}"); match self.kind() { ConstKind::Unevaluated(unevaluated) => { @@ -381,9 +325,9 @@ impl<'tcx> Const<'tcx> { ); return Err(e.into()); }; - Ok(c) + Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c)) } - ConstKind::Value(val) => Ok(val), + ConstKind::Value(ty, val) => Ok((ty, val)), ConstKind::Error(g) => Err(g.into()), ConstKind::Param(_) | ConstKind::Infer(_) @@ -397,8 +341,8 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { match self.eval(tcx, param_env, DUMMY_SP) { - Ok(val) => Self::new_value(tcx, val, self.ty()), - Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into(), self.ty()), + Ok((ty, val)) => Self::new_value(tcx, val, ty), + Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into()), Err(ErrorHandled::TooGeneric(_span)) => self, } } @@ -408,8 +352,10 @@ impl<'tcx> Const<'tcx> { self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - ) -> Option<Scalar> { - self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar() + ) -> Option<(Ty<'tcx>, Scalar)> { + let (ty, val) = self.eval(tcx, param_env, DUMMY_SP).ok()?; + let val = val.try_to_scalar()?; + Some((ty, val)) } #[inline] @@ -420,8 +366,10 @@ impl<'tcx> Const<'tcx> { self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, - ) -> Option<ScalarInt> { - self.try_eval_scalar(tcx, param_env)?.try_to_int().ok() + ) -> Option<(Ty<'tcx>, ScalarInt)> { + let (ty, scalar) = self.try_eval_scalar(tcx, param_env)?; + let val = scalar.try_to_int().ok()?; + Some((ty, val)) } #[inline] @@ -429,18 +377,17 @@ impl<'tcx> Const<'tcx> { /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it /// contains const generic parameters or pointers). pub fn try_eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> { - let int = self.try_eval_scalar_int(tcx, param_env)?; - let size = - tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size; + let (ty, scalar) = self.try_eval_scalar_int(tcx, param_env)?; + let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; // if `ty` does not depend on generic parameters, use an empty param_env - int.try_to_bits(size).ok() + scalar.try_to_bits(size).ok() } #[inline] /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u128 { self.try_eval_bits(tcx, param_env) - .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", self.ty(), self)) + .unwrap_or_else(|| bug!("failed to evalate {:#?} to bits", self)) } #[inline] @@ -449,12 +396,14 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option<u64> { - self.try_eval_scalar_int(tcx, param_env)?.try_to_target_usize(tcx).ok() + let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?; + scalar.try_to_target_usize(tcx).ok() } #[inline] pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> { - self.try_eval_scalar_int(tcx, param_env)?.try_into().ok() + let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?; + scalar.try_into().ok() } #[inline] @@ -467,7 +416,7 @@ impl<'tcx> Const<'tcx> { /// Panics if self.kind != ty::ConstKind::Value pub fn to_valtree(self) -> ty::ValTree<'tcx> { match self.kind() { - ty::ConstKind::Value(valtree) => valtree, + ty::ConstKind::Value(_, valtree) => valtree, _ => bug!("expected ConstKind::Value, got {:?}", self.kind()), } } @@ -475,7 +424,7 @@ impl<'tcx> Const<'tcx> { /// Attempts to convert to a `ValTree` pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> { match self.kind() { - ty::ConstKind::Value(valtree) => Some(valtree), + ty::ConstKind::Value(_, valtree) => Some(valtree), _ => None, } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 5f29acf5ed2..bf834ef7607 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -104,10 +104,12 @@ impl<'tcx> Expr<'tcx> { tcx: TyCtxt<'tcx>, func_ty: Ty<'tcx>, func_expr: Const<'tcx>, - arguments: impl Iterator<Item = Const<'tcx>>, + arguments: impl IntoIterator<Item = Const<'tcx>>, ) -> Self { let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( - [func_ty.into(), func_expr.into()].into_iter().chain(arguments.map(|ct| ct.into())), + [func_ty.into(), func_expr.into()] + .into_iter() + .chain(arguments.into_iter().map(|ct| ct.into())), ); Self { kind: ExprKind::FunctionCall, args } @@ -155,7 +157,7 @@ impl<'tcx> Expr<'tcx> { Self { kind, args } } - pub fn args(&self) -> ty::GenericArgsRef<'tcx> { + pub fn args(self) -> ty::GenericArgsRef<'tcx> { self.args } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 47f66c64406..f9a22aa72be 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -28,10 +28,10 @@ use crate::traits::solve::{ }; use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ - self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData, - GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, - PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity, - Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, Visibility, + self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericParamDefKind, + ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, PatternKind, + PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity, Region, + RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, Visibility, }; use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use rustc_ast::{self as ast, attr}; @@ -268,7 +268,7 @@ pub struct CtxtInterners<'tcx> { clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>, projs: InternedSet<'tcx, List<ProjectionKind>>, place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>, - const_: InternedSet<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>, + const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>, pat: InternedSet<'tcx, PatternKind<'tcx>>, const_allocation: InternedSet<'tcx, Allocation>, bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>, @@ -338,18 +338,18 @@ impl<'tcx> CtxtInterners<'tcx> { #[inline(never)] fn intern_const( &self, - data: ty::ConstData<'tcx>, + kind: ty::ConstKind<'tcx>, sess: &Session, untracked: &Untracked, ) -> Const<'tcx> { Const(Interned::new_unchecked( self.const_ - .intern(data, |data: ConstData<'_>| { - let flags = super::flags::FlagComputation::for_const(&data.kind, data.ty); - let stable_hash = self.stable_hash(&flags, sess, untracked, &data); + .intern(kind, |kind: ty::ConstKind<'_>| { + let flags = super::flags::FlagComputation::for_const_kind(&kind); + let stable_hash = self.stable_hash(&flags, sess, untracked, &kind); InternedInSet(self.arena.alloc(WithCachedTypeInfo { - internee: data, + internee: kind, stable_hash, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, @@ -601,18 +601,15 @@ impl<'tcx> CommonConsts<'tcx> { }; CommonConsts { - unit: mk_const(ty::ConstData { - kind: ty::ConstKind::Value(ty::ValTree::zst()), - ty: types.unit, - }), - true_: mk_const(ty::ConstData { - kind: ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::TRUE)), - ty: types.bool, - }), - false_: mk_const(ty::ConstData { - kind: ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::FALSE)), - ty: types.bool, - }), + unit: mk_const(ty::ConstKind::Value(types.unit, ty::ValTree::zst())), + true_: mk_const(ty::ConstKind::Value( + types.bool, + ty::ValTree::Leaf(ty::ScalarInt::TRUE), + )), + false_: mk_const(ty::ConstKind::Value( + types.bool, + ty::ValTree::Leaf(ty::ScalarInt::FALSE), + )), } } } @@ -2225,9 +2222,9 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { + pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> { self.interners.intern_const( - ty::ConstData { kind, ty }, + kind, self.sess, // This is only used to create a stable hashing context. &self.untracked, @@ -2252,14 +2249,10 @@ impl<'tcx> TyCtxt<'tcx> { ty::Region::new_early_param(self, param.to_early_bound_region_data()).into() } GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(), - GenericParamDefKind::Const { .. } => ty::Const::new_param( - self, - ParamConst { index: param.index, name: param.name }, - self.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), - ) - .into(), + GenericParamDefKind::Const { .. } => { + ty::Const::new_param(self, ParamConst { index: param.index, name: param.name }) + .into() + } } } diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 7508f0080cc..923667e609b 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -337,7 +337,7 @@ impl DeepRejectCtxt { | ty::ConstKind::Error(_) => { return true; } - ty::ConstKind::Value(impl_val) => impl_val, + ty::ConstKind::Value(_, impl_val) => impl_val, ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { bug!("unexpected impl arg: {:?}", impl_ct) } @@ -357,7 +357,7 @@ impl DeepRejectCtxt { ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => { true } - ty::ConstKind::Value(obl_val) => obl_val == impl_val, + ty::ConstKind::Value(_, obl_val) => obl_val == impl_val, ty::ConstKind::Infer(_) => true, diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 93a51d3a334..21c115c2c96 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -28,10 +28,9 @@ impl FlagComputation { result } - pub fn for_const(c: &ty::ConstKind<'_>, t: Ty<'_>) -> FlagComputation { + pub fn for_const_kind(kind: &ty::ConstKind<'_>) -> FlagComputation { let mut result = FlagComputation::new(); - result.add_const_kind(c); - result.add_ty(t); + result.add_const_kind(kind); result } @@ -373,7 +372,7 @@ impl FlagComputation { self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } - ty::ConstKind::Value(_) => {} + ty::ConstKind::Value(ty, _) => self.add_ty(ty), ty::ConstKind::Expr(e) => self.add_args(e.args()), ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index b5b36cbd1ba..9b5b1430c27 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -134,13 +134,13 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { pub trait BoundVarReplacerDelegate<'tcx> { fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx>; fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx>; - fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx>; + fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx>; } pub struct FnMutDelegate<'a, 'tcx> { pub regions: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a), pub types: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a), - pub consts: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a), + pub consts: &'a mut (dyn FnMut(ty::BoundVar) -> ty::Const<'tcx> + 'a), } impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> { @@ -150,8 +150,8 @@ impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> { fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> { (self.types)(bt) } - fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> { - (self.consts)(bv, ty) + fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> { + (self.consts)(bv) } } @@ -224,7 +224,7 @@ where fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => { - let ct = self.delegate.replace_const(bound_const, ct.ty()); + let ct = self.delegate.replace_const(bound_const); debug_assert!(!ct.has_vars_bound_above(ty::INNERMOST)); ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32()) } @@ -282,7 +282,7 @@ impl<'tcx> TyCtxt<'tcx> { let delegate = FnMutDelegate { regions: &mut replace_regions, types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"), - consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"), + consts: &mut |b| bug!("unexpected bound ct in binder: {b:?}"), }; let mut replacer = BoundVarReplacer::new(self, delegate); value.fold_with(&mut replacer) @@ -353,9 +353,7 @@ impl<'tcx> TyCtxt<'tcx> { ty::BoundTy { var: shift_bv(t.var), kind: t.kind }, ) }, - consts: &mut |c, ty: Ty<'tcx>| { - ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c), ty) - }, + consts: &mut |c| ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c)), }, ) } @@ -398,12 +396,12 @@ impl<'tcx> TyCtxt<'tcx> { .expect_ty(); Ty::new_bound(self.tcx, ty::INNERMOST, BoundTy { var, kind }) } - fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> { + fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> { let entry = self.map.entry(bv); let index = entry.index(); let var = ty::BoundVar::from_usize(index); let () = entry.or_insert_with(|| ty::BoundVariableKind::Const).expect_const(); - ty::Const::new_bound(self.tcx, ty::INNERMOST, var, ty) + ty::Const::new_bound(self.tcx, ty::INNERMOST, var) } } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index c3ab755175d..7fff3d01324 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -228,7 +228,7 @@ impl<'tcx> GenericArg<'tcx> { ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(), ))), CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked( - ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(), + ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(), ))), _ => intrinsics::unreachable(), } @@ -454,11 +454,11 @@ impl<'tcx> GenericArgs<'tcx> { def_id: DefId, original_args: &[GenericArg<'tcx>], ) -> GenericArgsRef<'tcx> { - ty::GenericArgs::for_item(tcx, def_id, |def, args| { + ty::GenericArgs::for_item(tcx, def_id, |def, _| { if let Some(arg) = original_args.get(def.index as usize) { *arg } else { - def.to_error(tcx, args) + def.to_error(tcx) } }) } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 89ba8cd2ad4..185dbe44735 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -100,19 +100,11 @@ impl GenericParamDef { } } - pub fn to_error<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - preceding_args: &[ty::GenericArg<'tcx>], - ) -> ty::GenericArg<'tcx> { + pub fn to_error<'tcx>(&self, tcx: TyCtxt<'tcx>) -> ty::GenericArg<'tcx> { match &self.kind { ty::GenericParamDefKind::Lifetime => ty::Region::new_error_misc(tcx).into(), ty::GenericParamDefKind::Type { .. } => Ty::new_misc_error(tcx).into(), - ty::GenericParamDefKind::Const { .. } => ty::Const::new_misc_error( - tcx, - tcx.type_of(self.def_id).instantiate(tcx, preceding_args), - ) - .into(), + ty::GenericParamDefKind::Const { .. } => ty::Const::new_misc_error(tcx).into(), } } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index a2df90b2c0f..142872009bf 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -385,9 +385,7 @@ impl<'tcx> SizeSkeleton<'tcx> { ), } } - ty::Array(inner, len) - if len.ty() == tcx.types.usize && tcx.features().transmute_generic_consts => - { + ty::Array(inner, len) if tcx.features().transmute_generic_consts => { let len_eval = len.try_eval_target_usize(tcx, param_env); if len_eval == Some(0) { return Ok(SizeSkeleton::Known(Size::from_bytes(0))); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c6028ef74a9..e0fbf127e70 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -87,7 +87,7 @@ pub use self::closure::{ CAPTURE_STRUCT_LOCAL, }; pub use self::consts::{ - Const, ConstData, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, + Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, }; pub use self::context::{ tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, @@ -617,7 +617,7 @@ impl<'tcx> Term<'tcx> { ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(), ))), CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked( - ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(), + ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(), ))), _ => core::intrinsics::unreachable(), } @@ -934,6 +934,30 @@ pub struct Placeholder<T> { pub universe: UniverseIndex, pub bound: T, } +impl Placeholder<BoundVar> { + pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { + let mut candidates = env.caller_bounds().iter().filter_map(|clause| { + // `ConstArgHasType` are never desugared to be higher ranked. + match clause.kind().skip_binder() { + ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => { + assert!(!(placeholder_ct, ty).has_escaping_bound_vars()); + + match placeholder_ct.kind() { + ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => { + Some(ty) + } + _ => None, + } + } + _ => None, + } + }); + + let ty = candidates.next().unwrap(); + assert!(candidates.next().is_none()); + ty + } +} pub type PlaceholderRegion = Placeholder<BoundRegion>; diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index bbcbcdce1b2..52902aadd7c 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -216,7 +216,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { }) .emit_unless(self.ignore_errors); - ty::Const::new_error(self.tcx, guar, ct.ty()) + ty::Const::new_error(self.tcx, guar) } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1b37078e703..3cfebaa6b57 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1459,23 +1459,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { return Ok(()); } - macro_rules! print_underscore { - () => {{ - if print_ty { - self.typed_value( - |this| { - write!(this, "_")?; - Ok(()) - }, - |this| this.print_type(ct.ty()), - ": ", - )?; - } else { - write!(self, "_")?; - } - }}; - } - match ct.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => { match self.tcx().def_kind(def) { @@ -1508,11 +1491,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::InferConst::Var(ct_vid) if let Some(name) = self.const_infer_name(ct_vid) => { p!(write("{}", name)) } - _ => print_underscore!(), + _ => write!(self, "_")?, }, ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)), - ty::ConstKind::Value(value) => { - return self.pretty_print_const_valtree(value, ct.ty(), print_ty); + ty::ConstKind::Value(ty, value) => { + return self.pretty_print_const_valtree(value, ty, print_ty); } ty::ConstKind::Bound(debruijn, bound_var) => { @@ -1666,7 +1649,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::Ref(_, inner, _) => { if let ty::Array(elem, len) = inner.kind() { if let ty::Uint(ty::UintTy::U8) = elem.kind() { - if let ty::ConstKind::Value(ty::ValTree::Leaf(int)) = len.kind() { + if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() { match self.tcx().try_get_global_alloc(prov.alloc_id()) { Some(GlobalAlloc::Memory(alloc)) => { let len = int.assert_bits(self.tcx().data_layout.pointer_size); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index a621d255a03..e24e64b2301 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -646,24 +646,25 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( true } (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2, - (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val, + (ty::ConstKind::Value(_, a_val), ty::ConstKind::Value(_, b_val)) => a_val == b_val, // While this is slightly incorrect, it shouldn't matter for `min_const_generics` // and is the better alternative to waiting until `generic_const_exprs` can // be stabilized. (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { - assert_eq!(a.ty(), b.ty()); + if cfg!(debug_assertions) { + let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args); + let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args); + assert_eq!(a_ty, b_ty); + } + let args = relation.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), au.args, bu.args, )?; - return Ok(ty::Const::new_unevaluated( - tcx, - ty::UnevaluatedConst { def: au.def, args }, - a.ty(), - )); + return Ok(ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { def: au.def, args })); } (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => { match (ae.kind, be.kind) { @@ -676,7 +677,7 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( } let args = relation.relate(ae.args(), be.args())?; - return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args), a.ty())); + return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args))); } _ => false, }; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 7a291b4dbff..cf4854d1364 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -201,26 +201,21 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::Const<'tcx> { f: &mut core::fmt::Formatter<'_>, ) -> core::fmt::Result { // If this is a value, we spend some effort to make it look nice. - if let ConstKind::Value(_) = this.data.kind() { + if let ConstKind::Value(_, _) = this.data.kind() { return ty::tls::with(move |tcx| { // Somehow trying to lift the valtree results in lifetime errors, so we lift the // entire constant. let lifted = tcx.lift(*this.data).unwrap(); - let ConstKind::Value(valtree) = lifted.kind() else { + let ConstKind::Value(ty, valtree) = lifted.kind() else { bug!("we checked that this is a valtree") }; let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); - cx.pretty_print_const_valtree(valtree, lifted.ty(), /*print_ty*/ true)?; + cx.pretty_print_const_valtree(valtree, ty, /*print_ty*/ true)?; f.write_str(&cx.into_buffer()) }); } // Fall back to something verbose. - write!( - f, - "{kind:?}: {ty:?}", - ty = &this.map(|data| data.ty()), - kind = &this.map(|data| data.kind()) - ) + write!(f, "{kind:?}", kind = &this.map(|data| data.kind())) } } @@ -647,7 +642,6 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { self, folder: &mut F, ) -> Result<Self, F::Error> { - let ty = self.ty().try_fold_with(folder)?; let kind = match self.kind() { ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?), ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?), @@ -656,21 +650,18 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { } ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?), ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?), - ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?), + ConstKind::Value(t, v) => { + ConstKind::Value(t.try_fold_with(folder)?, v.try_fold_with(folder)?) + } ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?), ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?), }; - if ty != self.ty() || kind != self.kind() { - Ok(folder.interner().mk_ct_from_kind(kind, ty)) - } else { - Ok(self) - } + if kind != self.kind() { Ok(folder.interner().mk_ct_from_kind(kind)) } else { Ok(self) } } } impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.ty().visit_with(visitor)); match self.kind() { ConstKind::Param(p) => p.visit_with(visitor), ConstKind::Infer(i) => i.visit_with(visitor), @@ -680,7 +671,10 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { } ConstKind::Placeholder(p) => p.visit_with(visitor), ConstKind::Unevaluated(uv) => uv.visit_with(visitor), - ConstKind::Value(v) => v.visit_with(visitor), + ConstKind::Value(t, v) => { + try_visit!(t.visit_with(visitor)); + v.visit_with(visitor) + } ConstKind::Error(e) => e.visit_with(visitor), ConstKind::Expr(e) => e.visit_with(visitor), } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 879396b0678..c83f6b0b9ec 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -21,6 +21,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi; +use rustc_type_ir::visit::TypeVisitableExt; use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; @@ -339,6 +340,27 @@ impl ParamConst { pub fn for_def(def: &ty::GenericParamDef) -> ParamConst { ParamConst::new(def.index, def.name) } + + pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { + let mut candidates = env.caller_bounds().iter().filter_map(|clause| { + // `ConstArgHasType` are never desugared to be higher ranked. + match clause.kind().skip_binder() { + ty::ClauseKind::ConstArgHasType(param_ct, ty) => { + assert!(!(param_ct, ty).has_escaping_bound_vars()); + + match param_ct.kind() { + ty::ConstKind::Param(param_ct) if param_ct.index == self.index => Some(ty), + _ => None, + } + } + _ => None, + } + }); + + let ty = candidates.next().unwrap(); + assert!(candidates.next().is_none()); + ty + } } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 58f69d772ec..e0f204a687f 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -212,21 +212,19 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) } }, GenericArgKind::Lifetime(_) => {} - GenericArgKind::Const(parent_ct) => { - stack.push(parent_ct.ty().into()); - match parent_ct.kind() { - ty::ConstKind::Infer(_) - | ty::ConstKind::Param(_) - | ty::ConstKind::Placeholder(_) - | ty::ConstKind::Bound(..) - | ty::ConstKind::Value(_) - | ty::ConstKind::Error(_) => {} - - ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()), - ty::ConstKind::Unevaluated(ct) => { - stack.extend(ct.args.iter().rev()); - } + GenericArgKind::Const(parent_ct) => match parent_ct.kind() { + ty::ConstKind::Infer(_) + | ty::ConstKind::Param(_) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Error(_) => {} + + ty::ConstKind::Value(ty, _) => stack.push(ty.into()), + + ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()), + ty::ConstKind::Unevaluated(ct) => { + stack.extend(ct.args.iter().rev()); } - } + }, } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index f7229326c54..b783eba8c4e 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput, use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{ - self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex, + self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex, }; use rustc_middle::{bug, span_bug}; use rustc_target::abi::Size; @@ -51,7 +51,7 @@ pub(crate) fn as_constant_inner<'tcx>( { Ok(c) => c, Err(LitToConstError::Reported(guar)) => { - Const::Ty(ty::Const::new_error(tcx, guar, ty)) + Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar)) } Err(LitToConstError::TypeError) => { bug!("encountered type error in `lit_to_mir_constant`") @@ -83,8 +83,8 @@ pub(crate) fn as_constant_inner<'tcx>( ConstOperand { user_ty, span, const_ } } ExprKind::ConstParam { param, def_id: _ } => { - let const_param = ty::Const::new_param(tcx, param, expr.ty); - let const_ = Const::Ty(const_param); + let const_param = ty::Const::new_param(tcx, param); + let const_ = Const::Ty(expr.ty, const_param); ConstOperand { user_ty: None, span, const_ } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 8d881713eeb..36495101d3f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -101,9 +101,9 @@ impl<'tcx> ConstToPat<'tcx> { // level of indirection can be eliminated let have_valtree = - matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_))); + matches!(cv, mir::Const::Ty(_, c) if matches!(c.kind(), ty::ConstKind::Value(_, _))); let inlined_const_as_pat = match cv { - mir::Const::Ty(c) => match c.kind() { + mir::Const::Ty(_, c) => match c.kind() { ty::ConstKind::Param(_) | ty::ConstKind::Infer(_) | ty::ConstKind::Bound(_, _) @@ -113,8 +113,8 @@ impl<'tcx> ConstToPat<'tcx> { | ty::ConstKind::Expr(_) => { span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind()) } - ty::ConstKind::Value(valtree) => { - self.recur(valtree, cv.ty()).unwrap_or_else(|_: FallbackToOpaqueConst| { + ty::ConstKind::Value(ty, valtree) => { + self.recur(valtree, ty).unwrap_or_else(|_: FallbackToOpaqueConst| { Box::new(Pat { span: self.span, ty: cv.ty(), @@ -336,9 +336,9 @@ impl<'tcx> ConstToPat<'tcx> { ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() { // `&str` is represented as a valtree, let's keep using this // optimization for now. - ty::Str => { - PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } - } + ty::Str => PatKind::Constant { + value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), + }, // All other references are converted into deref patterns and then recursively // convert the dereferenced constant to a pattern that is the sub-pattern of the // deref pattern. @@ -382,13 +382,15 @@ impl<'tcx> ConstToPat<'tcx> { self.saw_const_match_error.set(Some(e)); return Err(FallbackToOpaqueConst); } else { - PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } + PatKind::Constant { + value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), + } } } ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => { // The raw pointers we see here have been "vetted" by valtree construction to be // just integers, so we simply allow them. - PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } + PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) } } ty::FnPtr(..) => { unreachable!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 33401cad631..145a40ca3cd 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -580,7 +580,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { .tcx .const_eval_global_id_for_typeck(param_env_reveal_all, cid, span) .map(|val| match val { - Some(valtree) => mir::Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), + Some(valtree) => mir::Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)), None => mir::Const::Val( self.tcx .const_eval_global_id(param_env_reveal_all, cid, span) @@ -659,7 +659,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { }; if let Some(lit_input) = lit_input { match tcx.at(expr.span).lit_to_const(lit_input) { - Ok(c) => return self.const_to_pat(Const::Ty(c), id, span).kind, + Ok(c) => return self.const_to_pat(Const::Ty(ty, c), id, span).kind, // If an error occurred, ignore that it's a literal // and leave reporting the error up to const eval of // the unevaluated constant below. @@ -681,8 +681,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // but something more principled, like a trait query checking whether this can be turned into a valtree. if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span) { - let subpattern = - self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span); + let subpattern = self.const_to_pat( + Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)), + id, + span, + ); PatKind::InlineConstant { subpattern, def: def_id } } else { // If that fails, convert it to an opaque constant pattern. @@ -720,10 +723,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => span_bug!(expr.span, "not a literal: {:?}", expr), }; - let lit_input = - LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg }; + let ct_ty = self.typeck_results.expr_ty(expr); + let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg }; match self.tcx.at(expr.span).lit_to_const(lit_input) { - Ok(constant) => self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span).kind, + Ok(constant) => { + self.const_to_pat(Const::Ty(ct_ty, constant), expr.hir_id, lit.span).kind + } Err(LitToConstError::Reported(e)) => PatKind::Error(e), Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index e88b727a21e..a8caead46f2 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -203,7 +203,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { && let operand_ty = operand.ty(self.local_decls, self.tcx) && let Some(operand_ty) = operand_ty.builtin_deref(true) && let ty::Array(_, len) = operand_ty.kind() - && let Some(len) = Const::Ty(*len).try_eval_scalar_int(self.tcx, self.param_env) + && let Some(len) = Const::Ty(self.tcx.types.usize, *len) + .try_eval_scalar_int(self.tcx, self.param_env) { state.insert_value_idx(target_len, FlatSet::Elem(len.into()), self.map()); } @@ -221,7 +222,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { Rvalue::Len(place) => { let place_ty = place.ty(self.local_decls, self.tcx); if let ty::Array(_, len) = place_ty.ty.kind() { - Const::Ty(*len) + Const::Ty(self.tcx.types.usize, *len) .try_eval_scalar(self.tcx, self.param_env) .map_or(FlatSet::Top, FlatSet::Elem) } else if let [ProjectionElem::Deref] = place.projection[..] { diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 548e4e30936..acde16fcb75 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1118,7 +1118,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // Trivial case: we are fetching a statically known length. let place_ty = place.ty(self.local_decls, self.tcx).ty; if let ty::Array(_, len) = place_ty.kind() { - return self.insert_constant(Const::from_ty_const(*len, self.tcx)); + return self.insert_constant(Const::from_ty_const( + *len, + self.tcx.types.usize, + self.tcx, + )); } let mut inner = self.simplify_place_value(place, location)?; @@ -1140,7 +1144,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { && let Some(to) = to.builtin_deref(true) && let ty::Slice(..) = to.kind() { - return self.insert_constant(Const::from_ty_const(*len, self.tcx)); + return self.insert_constant(Const::from_ty_const( + *len, + self.tcx.types.usize, + self.tcx, + )); } // Fallback: a symbolic `Len`. diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 40db3e38fd3..6806c517c17 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -150,7 +150,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { return; } - let const_ = Const::from_ty_const(len, self.tcx); + let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx); let constant = ConstOperand { span: source_info.span, const_, user_ty: None }; *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); } diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index 2070895c900..d5e72706661 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -95,7 +95,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { *rvalue = Rvalue::Use(Operand::Constant(Box::new(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, - const_: Const::from_ty_const(len, self.tcx), + const_: Const::from_ty_const(len, self.tcx.types.usize, self.tcx), }))); } self.super_rvalue(rvalue, loc); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index dc13766d145..a3ca9e9f9cf 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -263,7 +263,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { fn visit_constant(&mut self, ct: &mir::ConstOperand<'tcx>, location: Location) { match ct.const_ { - mir::Const::Ty(c) => { + mir::Const::Ty(_, c) => { c.visit_with(self); } mir::Const::Unevaluated(mir::UnevaluatedConst { def, args: _, promoted }, ty) => { diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 127ebde5fec..f22e24ef654 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -386,23 +386,15 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> } fn fold_const(&mut self, c: I::Const) -> I::Const { - // We could canonicalize all consts with static types, but the only ones we - // *really* need to worry about are the ones that we end up putting into `CanonicalVarKind` - // since canonical vars can't reference other canonical vars. - let ty = c - .ty() - .fold_with(&mut RegionsToStatic { interner: self.interner(), binder: ty::INNERMOST }); let kind = match c.kind() { ty::ConstKind::Infer(i) => match i { ty::InferConst::Var(vid) => { - // We compare `kind`s here because we've folded the `ty` with `RegionsToStatic` - // so we'll get a mismatch in types if it actually changed any regions. assert_eq!( - self.infcx.opportunistic_resolve_ct_var(vid, ty).kind(), - c.kind(), - "region vid should have been resolved fully before canonicalization" + self.infcx.opportunistic_resolve_ct_var(vid), + c, + "const vid should have been resolved fully before canonicalization" ); - CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty) + CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap()) } ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect, ty::InferConst::Fresh(_) => todo!(), @@ -410,23 +402,21 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode { CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst( PlaceholderLike::new(placeholder.universe(), self.variables.len().into()), - ty, ), CanonicalizeMode::Response { .. } => { - CanonicalVarKind::PlaceholderConst(placeholder, ty) + CanonicalVarKind::PlaceholderConst(placeholder) } }, ty::ConstKind::Param(_) => match self.canonicalize_mode { CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst( PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()), - ty, ), CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"), }, // FIXME: See comment above -- we could fold the region separately or something. ty::ConstKind::Bound(_, _) | ty::ConstKind::Unevaluated(_) - | ty::ConstKind::Value(_) + | ty::ConstKind::Value(_, _) | ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => return c.super_fold_with(self), }; @@ -440,34 +430,6 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> }), ); - Const::new_anon_bound(self.interner(), self.binder_index, var, ty) - } -} - -struct RegionsToStatic<I> { - interner: I, - binder: ty::DebruijnIndex, -} - -impl<I: Interner> TypeFolder<I> for RegionsToStatic<I> { - fn interner(&self) -> I { - self.interner - } - - fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T> - where - T: TypeFoldable<I>, - { - self.binder.shift_in(1); - let t = t.super_fold_with(self); - self.binder.shift_out(1); - t - } - - fn fold_region(&mut self, r: I::Region) -> I::Region { - match r.kind() { - ty::ReBound(db, _) if self.binder > db => r, - _ => Region::new_static(self.interner()), - } + Const::new_anon_bound(self.interner(), self.binder_index, var) } } diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs index 1333b4aa7d8..92e05cc4901 100644 --- a/compiler/rustc_next_trait_solver/src/resolve.rs +++ b/compiler/rustc_next_trait_solver/src/resolve.rs @@ -58,8 +58,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerRes fn fold_const(&mut self, c: I::Const) -> I::Const { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { - let ty = c.ty().fold_with(self); - let resolved = self.infcx.opportunistic_resolve_ct_var(vid, ty); + let resolved = self.infcx.opportunistic_resolve_ct_var(vid); if c != resolved && resolved.has_infer() { resolved.fold_with(self) } else { @@ -67,9 +66,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerRes } } ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => { - let bool = Ty::new_bool(self.infcx.interner()); - debug_assert_eq!(c.ty(), bool); - self.infcx.opportunistic_resolve_effect_var(vid, bool) + self.infcx.opportunistic_resolve_effect_var(vid) } _ => { if c.has_infer() { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index ff68dd81bea..81c5f355231 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -737,7 +737,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { // this). We show this to the user as `usize::MAX..` which is slightly incorrect but // probably clear enough. let c = ty.numeric_max_val(cx.tcx).unwrap(); - let value = mir::Const::from_ty_const(c, cx.tcx); + let value = mir::Const::from_ty_const(c, ty.0, cx.tcx); lo = PatRangeBoundary::Finite(value); } let hi = if let Some(hi) = range.hi.minus_one() { diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index d67132d2dd4..0be8b5d5718 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -68,6 +68,8 @@ fn compress<'tcx>( fn encode_args<'tcx>( tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, + for_def: DefId, + has_erased_self: bool, dict: &mut FxHashMap<DictKey<'tcx>, usize>, options: EncodeTyOptions, ) -> String { @@ -76,7 +78,8 @@ fn encode_args<'tcx>( let args: Vec<GenericArg<'_>> = args.iter().collect(); if !args.is_empty() { s.push('I'); - for arg in args { + let def_generics = tcx.generics_of(for_def); + for (n, arg) in args.iter().enumerate() { match arg.unpack() { GenericArgKind::Lifetime(region) => { s.push_str(&encode_region(region, dict)); @@ -85,7 +88,10 @@ fn encode_args<'tcx>( s.push_str(&encode_ty(tcx, ty, dict, options)); } GenericArgKind::Const(c) => { - s.push_str(&encode_const(tcx, c, dict, options)); + let n = n + (has_erased_self as usize); + let ct_ty = + tcx.type_of(def_generics.param_at(n, tcx).def_id).instantiate_identity(); + s.push_str(&encode_const(tcx, c, ct_ty, dict, options)); } } } @@ -99,6 +105,7 @@ fn encode_args<'tcx>( fn encode_const<'tcx>( tcx: TyCtxt<'tcx>, c: Const<'tcx>, + ct_ty: Ty<'tcx>, dict: &mut FxHashMap<DictKey<'tcx>, usize>, options: EncodeTyOptions, ) -> String { @@ -111,20 +118,20 @@ fn encode_const<'tcx>( // L<element-type>E as literal argument // Element type - s.push_str(&encode_ty(tcx, c.ty(), dict, options)); + s.push_str(&encode_ty(tcx, ct_ty, dict, options)); } // Literal arguments - ty::ConstKind::Value(..) => { + ty::ConstKind::Value(ct_ty, ..) => { // L<element-type>[n]<element-value>E as literal argument // Element type - s.push_str(&encode_ty(tcx, c.ty(), dict, options)); + s.push_str(&encode_ty(tcx, ct_ty, dict, options)); // The only allowed types of const values are bool, u8, u16, u32, // u64, u128, usize i8, i16, i32, i64, i128, isize, and char. The // bool value false is encoded as 0 and true as 1. - match c.ty().kind() { + match ct_ty.kind() { ty::Int(ity) => { let bits = c.eval_bits(tcx, ty::ParamEnv::reveal_all()); let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; @@ -142,7 +149,7 @@ fn encode_const<'tcx>( let _ = write!(s, "{val}"); } _ => { - bug!("encode_const: unexpected type `{:?}`", c.ty()); + bug!("encode_const: unexpected type `{:?}`", ct_ty); } } } @@ -231,15 +238,21 @@ fn encode_predicate<'tcx>( ty::ExistentialPredicate::Trait(trait_ref) => { let name = encode_ty_name(tcx, trait_ref.def_id); let _ = write!(s, "u{}{}", name.len(), &name); - s.push_str(&encode_args(tcx, trait_ref.args, dict, options)); + s.push_str(&encode_args(tcx, trait_ref.args, trait_ref.def_id, true, dict, options)); } ty::ExistentialPredicate::Projection(projection) => { let name = encode_ty_name(tcx, projection.def_id); let _ = write!(s, "u{}{}", name.len(), &name); - s.push_str(&encode_args(tcx, projection.args, dict, options)); + s.push_str(&encode_args(tcx, projection.args, projection.def_id, true, dict, options)); match projection.term.unpack() { TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)), - TermKind::Const(c) => s.push_str(&encode_const(tcx, c, dict, options)), + TermKind::Const(c) => s.push_str(&encode_const( + tcx, + c, + tcx.type_of(projection.def_id).instantiate(tcx, projection.args), + dict, + options, + )), } } ty::ExistentialPredicate::AutoTrait(def_id) => { @@ -485,7 +498,7 @@ pub fn encode_ty<'tcx>( // <subst>, as vendor extended type. let name = encode_ty_name(tcx, def_id); let _ = write!(s, "u{}{}", name.len(), &name); - s.push_str(&encode_args(tcx, args, dict, options)); + s.push_str(&encode_args(tcx, args, def_id, false, dict, options)); compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); } typeid.push_str(&s); @@ -529,7 +542,7 @@ pub fn encode_ty<'tcx>( let mut s = String::new(); let name = encode_ty_name(tcx, *def_id); let _ = write!(s, "u{}{}", name.len(), &name); - s.push_str(&encode_args(tcx, args, dict, options)); + s.push_str(&encode_args(tcx, args, *def_id, false, dict, options)); compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); typeid.push_str(&s); } @@ -541,7 +554,7 @@ pub fn encode_ty<'tcx>( let name = encode_ty_name(tcx, *def_id); let _ = write!(s, "u{}{}", name.len(), &name); let parent_args = tcx.mk_args(args.as_coroutine_closure().parent_args()); - s.push_str(&encode_args(tcx, parent_args, dict, options)); + s.push_str(&encode_args(tcx, parent_args, *def_id, false, dict, options)); compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); typeid.push_str(&s); } @@ -556,6 +569,8 @@ pub fn encode_ty<'tcx>( s.push_str(&encode_args( tcx, tcx.mk_args(args.as_coroutine().parent_args()), + *def_id, + false, dict, options, )); diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index edfd48ed43b..c33a52f4a7a 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -251,7 +251,9 @@ impl RustcInternal for MirConst { fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { let constant = tables.mir_consts[self.id]; match constant { - rustc_middle::mir::Const::Ty(ty) => rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap()), + rustc_middle::mir::Const::Ty(ty, ct) => { + rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap()) + } rustc_middle::mir::Const::Unevaluated(uneval, ty) => { rustc_middle::mir::Const::Unevaluated( tcx.lift(uneval).unwrap(), diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 9822ed79e2b..8b09c5aef2f 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -398,7 +398,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ))); } - Ok(mir::Const::Ty(ty::Const::zero_sized(tables.tcx, ty_internal)).stable(&mut *tables)) + Ok(mir::Const::Ty(ty_internal, ty::Const::zero_sized(tables.tcx, ty_internal)) + .stable(&mut *tables)) } fn new_const_str(&self, value: &str) -> MirConst { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 1c87293209c..bcacf54baf3 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -729,9 +729,9 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap()); match *self { - mir::Const::Ty(c) => MirConst::new( + mir::Const::Ty(ty, c) => MirConst::new( stable_mir::ty::ConstantKind::Ty(c.stable(tables)), - c.ty().stable(tables), + ty.stable(tables), id, ), mir::Const::Unevaluated(unev_const, ty) => { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 1f3356f579f..73bc87dc9ab 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -415,7 +415,7 @@ pub fn mir_const_from_ty_const<'tcx>( ty: Ty<'tcx>, ) -> stable_mir::ty::MirConst { let kind = match ty_const.kind() { - ty::Value(val) => { + ty::Value(ty, val) => { let val = match val { ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar), ty::ValTree::Branch(branch) => { @@ -447,7 +447,7 @@ pub fn mir_const_from_ty_const<'tcx>( ty::ExprCt(_) => unimplemented!(), }; let stable_ty = tables.intern_ty(ty); - let id = tables.intern_mir_const(mir::Const::Ty(ty_const)); + let id = tables.intern_mir_const(mir::Const::Ty(ty, ty_const)); stable_mir::ty::MirConst::new(kind, stable_ty, id) } @@ -456,14 +456,15 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { let kind = match self.kind() { - ty::Value(val) => { + ty::Value(ty, val) => { let val = match val { ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar), ty::ValTree::Branch(branch) => { ty::ValTree::Branch(tables.tcx.lift(branch).unwrap()) } }; - let ty = tables.tcx.lift(self.ty()).unwrap(); + + let ty = tables.tcx.lift(ty).unwrap(); let const_val = tables.tcx.valtree_to_const_val((ty, val)); if matches!(const_val, mir::ConstValue::ZeroSized) { stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables)) diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 0ed1f67bb82..75cac6c7992 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -270,15 +270,15 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> { // only print integers - match (ct.kind(), ct.ty().kind()) { - (ty::ConstKind::Value(ty::ValTree::Leaf(scalar)), ty::Int(_) | ty::Uint(_)) => { + match ct.kind() { + ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar)) if ty.is_integral() => { // The `pretty_print_const` formatting depends on -Zverbose-internals // flag, so we cannot reuse it here. - let signed = matches!(ct.ty().kind(), ty::Int(_)); + let signed = matches!(ty.kind(), ty::Int(_)); write!( self, "{:#?}", - ty::ConstInt::new(scalar, signed, ct.ty().is_ptr_sized_integral()) + ty::ConstInt::new(scalar, signed, ty.is_ptr_sized_integral()) )?; } _ => self.write_str("_")?, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 57b1542ff5a..55479bce6fc 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -541,8 +541,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> { // We only mangle a typed value if the const can be evaluated. let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all()); - match ct.kind() { - ty::ConstKind::Value(_) => {} + let (ct_ty, valtree) = match ct.kind() { + ty::ConstKind::Value(ty, val) => (ty, val), // Placeholders (should be demangled as `_`). // NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore @@ -559,7 +559,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { self.push("p"); return Ok(()); } - } + }; if let Some(&i) = self.consts.get(&ct) { self.print_backref(i)?; @@ -567,16 +567,15 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { } let start = self.out.len(); - let ty = ct.ty(); - match ty.kind() { + match ct_ty.kind() { ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => { - ty.print(self)?; + ct_ty.print(self)?; let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all()); // Negative integer values are mangled using `n` as a "sign prefix". - if let ty::Int(ity) = ty.kind() { + if let ty::Int(ity) = ct_ty.kind() { let val = Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128; if val < 0 { @@ -598,40 +597,32 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { match inner_ty.kind() { ty::Str if mutbl.is_not() => { - match ct.kind() { - ty::ConstKind::Value(valtree) => { - let slice = - valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| { - bug!( - "expected to get raw bytes from valtree {:?} for type {:}", - valtree, ty - ) - }); - let s = std::str::from_utf8(slice) - .expect("non utf8 str from MIR interpreter"); - - self.push("e"); - - // FIXME(eddyb) use a specialized hex-encoding loop. - for byte in s.bytes() { - let _ = write!(self.out, "{byte:02x}"); - } - - self.push("_"); - } - - _ => { - bug!("symbol_names: unsupported `&str` constant: {:?}", ct); - } + let slice = + valtree.try_to_raw_bytes(self.tcx(), ct_ty).unwrap_or_else(|| { + bug!( + "expected to get raw bytes from valtree {:?} for type {:}", + valtree, + ct_ty + ) + }); + let s = + std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter"); + + self.push("e"); + + // FIXME(eddyb) use a specialized hex-encoding loop. + for byte in s.bytes() { + let _ = write!(self.out, "{byte:02x}"); } + + self.push("_"); } _ => { - let pointee_ty = ct - .ty() + let pointee_ty = ct_ty .builtin_deref(true) .expect("tried to dereference on non-ptr type"); - // FIXME(const_generics): add an assert that we only do this for valtrees. - let dereferenced_const = self.tcx.mk_ct_from_kind(ct.kind(), pointee_ty); + let dereferenced_const = + ty::Const::new_value(self.tcx, valtree, pointee_ty); dereferenced_const.print(self)?; } } @@ -649,7 +640,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { Ok(()) }; - match *ct.ty().kind() { + match *ct_ty.kind() { ty::Array(..) | ty::Slice(_) => { self.push("A"); print_field_list(self)?; @@ -698,7 +689,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { } } _ => { - bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty(), ct); + bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct_ty, ct); } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 690c1797f23..0e0b9e98339 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -444,7 +444,7 @@ pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable<TyCtxt infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)).into() } ty::GenericArgKind::Type(_) => infcx.next_ty_var(span).into(), - ty::GenericArgKind::Const(ct) => infcx.next_const_var(ct.ty(), span).into(), + ty::GenericArgKind::Const(_) => infcx.next_const_var(span).into(), }; orig_values.push(unconstrained); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index f18f1f4f8f0..f90e4711037 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -609,8 +609,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ty } - pub(super) fn next_const_infer(&mut self, ty: Ty<'tcx>) -> ty::Const<'tcx> { - let ct = self.infcx.next_const_var(ty, DUMMY_SP); + pub(super) fn next_const_infer(&mut self) -> ty::Const<'tcx> { + let ct = self.infcx.next_const_var(DUMMY_SP); self.inspect.add_var_value(ct); ct } @@ -620,7 +620,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { pub(super) fn next_term_infer_of_kind(&mut self, kind: ty::Term<'tcx>) -> ty::Term<'tcx> { match kind.unpack() { ty::TermKind::Ty(_) => self.next_ty_infer().into(), - ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(), + ty::TermKind::Const(_) => self.next_const_infer().into(), } } @@ -1037,14 +1037,19 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &self, param_env: ty::ParamEnv<'tcx>, unevaluated: ty::UnevaluatedConst<'tcx>, - ty: Ty<'tcx>, ) -> Option<ty::Const<'tcx>> { use rustc_middle::mir::interpret::ErrorHandled; match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) { - Ok(Some(val)) => Some(ty::Const::new_value(self.interner(), val, ty)), + Ok(Some(val)) => Some(ty::Const::new_value( + self.interner(), + val, + self.interner() + .type_of(unevaluated.def) + .instantiate(self.interner(), unevaluated.args), + )), Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None, Err(ErrorHandled::Reported(e, _)) => { - Some(ty::Const::new_error(self.interner(), e.into(), ty)) + Some(ty::Const::new_error(self.interner(), e.into())) } } } @@ -1124,7 +1129,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceAliasWithInfer<'_, '_, 'tcx> { fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Unevaluated(..) if !ct.has_escaping_bound_vars() => { - let infer_ct = self.ecx.next_const_infer(ct.ty()); + let infer_ct = self.ecx.next_const_infer(); let normalizes_to = ty::PredicateKind::AliasRelate( ct.into(), infer_ct.into(), diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 1f27978e5a6..19c95dad48c 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -208,7 +208,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { let unconstrained_term = match term.unpack() { ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(), - ty::TermKind::Const(ct) => infcx.next_const_var(ct.ty(), span).into(), + ty::TermKind::Const(_) => infcx.next_const_var(span).into(), }; let goal = goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term }); diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 68a4831c335..c47b0194964 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -169,7 +169,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { // FIXME(generic_const_exprs): Implement handling for generic // const expressions here. - if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv, ct.ty()) { + if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv) { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) @@ -178,7 +178,9 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { ty::ConstKind::Infer(_) => { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } - ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => { + ty::ConstKind::Placeholder(_) + | ty::ConstKind::Value(_, _) + | ty::ConstKind::Error(_) => { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } // We can freely ICE here as: @@ -198,29 +200,37 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { ) -> QueryResult<'tcx> { let (ct, ty) = goal.predicate; - // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant - // other than `ConstKind::Value`. Unfortunately this would require looking in the - // env for any `ConstArgHasType` assumptions for parameters and placeholders. I - // have not yet gotten around to implementing this though. - // - // We do still stall on infer vars though as otherwise a goal like: - // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later - // get unified with some const that is not of type `usize`. - match ct.kind() { + let ct_ty = match ct.kind() { // FIXME: Ignore effect vars because canonicalization doesn't handle them correctly // and if we stall on the var then we wind up creating ambiguity errors in a probe // for this goal which contains an effect var. Which then ends up ICEing. - ty::ConstKind::Infer(ty::InferConst::Var(_)) => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + ty::ConstKind::Infer(ty::InferConst::EffectVar(_)) => { + return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); + } + ty::ConstKind::Infer(_) => { + return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); } ty::ConstKind::Error(_) => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } - _ => { - self.eq(goal.param_env, ct.ty(), ty)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ty::ConstKind::Unevaluated(uv) => { + self.interner().type_of(uv.def).instantiate(self.interner(), uv.args) } - } + ty::ConstKind::Expr(_) => unimplemented!( + "`feature(generic_const_exprs)` is not supported in the new trait solver" + ), + ty::ConstKind::Param(_) => { + unreachable!("`ConstKind::Param` should have been canonicalized to `Placeholder`") + } + ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct), + ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Placeholder(placeholder) => { + placeholder.find_const_ty_from_env(goal.param_env) + } + }; + + self.eq(goal.param_env, ct_ty, ty)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index c60d1aed415..f42edebfcc4 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -109,7 +109,6 @@ where fn normalize_unevaluated_const( &mut self, - ty: Ty<'tcx>, uv: ty::UnevaluatedConst<'tcx>, ) -> Result<ty::Const<'tcx>, Vec<E>> { let infcx = self.at.infcx; @@ -126,7 +125,7 @@ where self.depth += 1; - let new_infer_ct = infcx.next_const_var(ty, self.at.cause.span); + let new_infer_ct = infcx.next_const_var(self.at.cause.span); let obligation = Obligation::new( tcx, self.at.cause.clone(), @@ -143,7 +142,7 @@ where let ct = infcx.resolve_vars_if_possible(new_infer_ct); ct.try_fold_with(self)? } else { - ty::Const::new_unevaluated(tcx, uv, ty).try_super_fold_with(self)? + ty::Const::new_unevaluated(tcx, uv).try_super_fold_with(self)? }; self.depth -= 1; @@ -214,7 +213,7 @@ where if uv.has_escaping_bound_vars() { let (uv, mapped_regions, mapped_types, mapped_consts) = BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, uv); - let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct.ty(), uv))?; + let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))?; Ok(PlaceholderReplacer::replace_placeholders( infcx, mapped_regions, @@ -224,7 +223,7 @@ where result, )) } else { - ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct.ty(), uv)) + ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv)) } } } diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs index 362c4072278..a6e4b6ff4a8 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs @@ -12,10 +12,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { if let Some(normalized_const) = self.try_const_eval_resolve( goal.param_env, ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args), - self.interner() - .type_of(goal.predicate.alias.def_id) - .no_bound_vars() - .expect("const ty should not rely on other generics"), ) { self.instantiate_normalizes_to_term(goal, normalized_const.into()); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 8c63bd824bc..787f08a084e 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -201,13 +201,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let error_response = |ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, reason| { let guar = tcx.dcx().span_delayed_bug(tcx.def_span(assoc_def.item.def_id), reason); let error_term = match assoc_def.item.kind { - ty::AssocKind::Const => ty::Const::new_error( - tcx, - guar, - tcx.type_of(goal.predicate.def_id()) - .instantiate(tcx, goal.predicate.alias.args), - ) - .into(), + ty::AssocKind::Const => ty::Const::new_error(tcx, guar).into(), ty::AssocKind::Type => Ty::new_error(tcx, guar).into(), // This makes no sense... ty::AssocKind::Fn => span_bug!( @@ -253,7 +247,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ty::EarlyBinder::bind( ty::Const::new_error_with_message( tcx, - tcx.type_of(assoc_def.item.def_id).instantiate_identity(), DUMMY_SP, "associated const projection is not supported yet", ) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6623a86e69f..1d32ef2ccd9 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -765,7 +765,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { unevaluated, obligation.cause.span, ) { - Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, c.ty())), + Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args))), Ok(None) => { let tcx = self.tcx; let reported = diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 5cfc41cc2a2..1ef2f26cd09 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -529,7 +529,6 @@ fn plug_infer_with_placeholders<'tcx>( ty::Const::new_placeholder( self.infcx.tcx, ty::Placeholder { universe: self.universe, bound: self.next_var() }, - ct.ty(), ), ) else { diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 8348482386f..f93bd0a396d 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -34,7 +34,7 @@ pub fn is_const_evaluatable<'tcx>( ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Placeholder(_) - | ty::ConstKind::Value(_) + | ty::ConstKind::Value(_, _) | ty::ConstKind::Error(_) => return Ok(()), ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer), }; @@ -173,8 +173,7 @@ fn satisfied_from_param_env<'tcx>( debug!("is_const_evaluatable: candidate={:?}", c); if self.infcx.probe(|_| { let ocx = ObligationCtxt::new(self.infcx); - ocx.eq(&ObligationCause::dummy(), self.param_env, c.ty(), self.ct.ty()).is_ok() - && ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok() + ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok() && ocx.select_all_or_error().is_empty() }) { self.single_match = match self.single_match { @@ -215,7 +214,6 @@ fn satisfied_from_param_env<'tcx>( if let Some(Ok(c)) = single_match { let ocx = ObligationCtxt::new(infcx); - assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok()); assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok()); assert!(ocx.select_all_or_error().is_empty()); return true; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 9a0929baeaf..46b13788186 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -876,56 +876,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => { - // Errors for `ConstEvaluatable` predicates show up as - // `SelectionError::ConstEvalFailure`, - // not `Unimplemented`. + // Errors for `ConstEvaluatable` predicates show up as + // `SelectionError::ConstEvalFailure`, + // not `Unimplemented`. + ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) + // Errors for `ConstEquate` predicates show up as + // `SelectionError::ConstEvalFailure`, + // not `Unimplemented`. + | ty::PredicateKind::ConstEquate { .. } + // Ambiguous predicates should never error + | ty::PredicateKind::Ambiguous + | ty::PredicateKind::NormalizesTo { .. } + | ty::PredicateKind::AliasRelate { .. } + | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => { span_bug!( span, - "const-evaluatable requirement gave wrong error: `{:?}`", + "Unexpected `Predicate` for `SelectionError`: `{:?}`", obligation ) } - - ty::PredicateKind::ConstEquate(..) => { - // Errors for `ConstEquate` predicates show up as - // `SelectionError::ConstEvalFailure`, - // not `Unimplemented`. - span_bug!( - span, - "const-equate requirement gave wrong error: `{:?}`", - obligation - ) - } - - ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"), - - ty::PredicateKind::NormalizesTo(..) => span_bug!( - span, - "NormalizesTo predicate should never be the predicate cause of a SelectionError" - ), - - ty::PredicateKind::AliasRelate(..) => span_bug!( - span, - "AliasRelate predicate should never be the predicate cause of a SelectionError" - ), - - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - let mut diag = self.dcx().struct_span_err( - span, - format!("the constant `{ct}` is not of type `{ty}`"), - ); - self.note_type_err( - &mut diag, - &obligation.cause, - None, - None, - TypeError::Sorts(ty::error::ExpectedFound::new(true, ty, ct.ty())), - false, - false, - ); - diag - } } } @@ -988,6 +957,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Overflow(_) => { bug!("overflow should be handled before the `report_selection_error` path"); } + + SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty } => { + let mut diag = self.dcx().struct_span_err( + span, + format!("the constant `{ct}` is not of type `{expected_ty}`"), + ); + + self.note_type_err( + &mut diag, + &obligation.cause, + None, + None, + TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)), + false, + false, + ); + diag + } }; self.note_obligation_cause(&mut err, &obligation); diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index a26288efc96..bce5c7101cc 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -439,37 +439,50 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { // This is because this is not ever a useful obligation to report // as the cause of an overflow. ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant - // other than `ConstKind::Value`. Unfortunately this would require looking in the - // env for any `ConstArgHasType` assumptions for parameters and placeholders. I - // don't really want to implement this in the old solver so I haven't. - // - // We do still stall on infer vars though as otherwise a goal like: - // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later - // get unified with some const that is not of type `usize`. - let ct = self.selcx.infcx.shallow_resolve_const(ct); - match ct.kind() { - ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { + let ct = infcx.shallow_resolve_const(ct); + let ct_ty = match ct.kind() { + ty::ConstKind::Infer(var) => { + let var = match var { + ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid), + ty::InferConst::EffectVar(vid) => TyOrConstInferVar::Effect(vid), + ty::InferConst::Fresh(_) => { + bug!("encountered fresh const in fulfill") + } + }; pending_obligation.stalled_on.clear(); - pending_obligation.stalled_on.extend([TyOrConstInferVar::Const(vid)]); - ProcessResult::Unchanged + pending_obligation.stalled_on.extend([var]); + return ProcessResult::Unchanged; } ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]), - _ => { - match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( - // Only really excercised by generic_const_exprs - DefineOpaqueTypes::Yes, - ct.ty(), - ty, - ) { - Ok(inf_ok) => { - ProcessResult::Changed(mk_pending(inf_ok.into_obligations())) - } - Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select( - SelectionError::Unimplemented, - )), - } + ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Unevaluated(uv) => { + infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) + } + // FIXME(generic_const_exprs): we should construct an alias like + // `<lhs_ty as Add<rhs_ty>>::Output` when this is an `Expr` representing + // `lhs + rhs`. + ty::ConstKind::Expr(_) => { + return ProcessResult::Changed(mk_pending(vec![])); + } + ty::ConstKind::Placeholder(_) => { + bug!("placeholder const {:?} in old solver", ct) + } + ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct), + ty::ConstKind::Param(param_ct) => { + param_ct.find_ty_from_env(obligation.param_env) } + }; + + match infcx.at(&obligation.cause, obligation.param_env).eq( + // Only really excercised by generic_const_exprs + DefineOpaqueTypes::Yes, + ct_ty, + ty, + ) { + Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())), + Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select( + SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty }, + )), } } @@ -633,7 +646,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { match self.selcx.infcx.try_const_eval_resolve( obligation.param_env, unevaluated, - c.ty(), obligation.cause.span, ) { Ok(val) => Ok(val), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index d918945dbed..7be2c4a85c5 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -359,7 +359,7 @@ pub fn normalize_param_env_or_error<'tcx>( // `ty::Const::normalize` can only work with properly preserved binders. if c.has_escaping_bound_vars() { - return ty::Const::new_misc_error(self.0, c.ty()); + return ty::Const::new_misc_error(self.0); } // While it is pretty sus to be evaluating things with an empty param env, it // should actually be okay since without `feature(generic_const_exprs)` the only diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 501d9c9266e..2c9cb79664b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -523,16 +523,9 @@ fn normalize_to_error<'a, 'tcx>( | ty::AliasTermKind::InherentTy | ty::AliasTermKind::OpaqueTy | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(), - ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => selcx - .infcx - .next_const_var( - selcx - .tcx() - .type_of(projection_term.def_id) - .instantiate(selcx.tcx(), projection_term.args), - cause.span, - ) - .into(), + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { + selcx.infcx.next_const_var(cause.span).into() + } }; let trait_obligation = Obligation { cause, @@ -744,8 +737,6 @@ fn project<'cx, 'tcx>( obligation.predicate.def_id, obligation.predicate.args, ), - tcx.type_of(obligation.predicate.def_id) - .instantiate(tcx, obligation.predicate.args), ) .into(), kind => { @@ -2071,15 +2062,14 @@ fn confirm_impl_candidate<'cx, 'tcx>( // * `args` ends up as `[u32, S]` let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args); let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node); - let ty = tcx.type_of(assoc_ty.item.def_id); let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst); let term: ty::EarlyBinder<'tcx, ty::Term<'tcx>> = if is_const { let did = assoc_ty.item.def_id; let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did); let uv = ty::UnevaluatedConst::new(did, identity_args); - ty.map_bound(|ty| ty::Const::new_unevaluated(tcx, uv, ty).into()) + ty::EarlyBinder::bind(ty::Const::new_unevaluated(tcx, uv).into()) } else { - ty.map_bound(|ty| ty.into()) + tcx.type_of(assoc_ty.item.def_id).map_bound(|ty| ty.into()) }; if !tcx.check_args_compatible(assoc_ty.item.def_id, args) { let err = Ty::new_error_with_message( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index ef0d8735d35..749081006f3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -665,9 +665,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { tcx, ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1), - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), ) .into() } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2489b8916d1..ce4fa5fa47c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -947,7 +947,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.infcx.try_const_eval_resolve( obligation.param_env, unevaluated, - c.ty(), obligation.cause.span, ) { Ok(val) => Ok(val), @@ -995,21 +994,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant - // other than `ConstKind::Value`. Unfortunately this would require looking in the - // env for any `ConstArgHasType` assumptions for parameters and placeholders. I - // don't really want to implement this in the old solver so I haven't. - // - // We do still stall on infer vars though as otherwise a goal like: - // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later - // get unified with some const that is not of type `usize`. let ct = self.infcx.shallow_resolve_const(ct); let ct_ty = match ct.kind() { - ty::ConstKind::Infer(ty::InferConst::Var(_)) => { + ty::ConstKind::Infer(_) => { return Ok(EvaluatedToAmbig); } ty::ConstKind::Error(_) => return Ok(EvaluatedToOk), - _ => ct.ty(), + ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Unevaluated(uv) => { + self.tcx().type_of(uv.def).instantiate(self.tcx(), uv.args) + } + // FIXME(generic_const_exprs): See comment in `fulfill.rs` + ty::ConstKind::Expr(_) => return Ok(EvaluatedToOk), + ty::ConstKind::Placeholder(_) => { + bug!("placeholder const {:?} in old solver", ct) + } + ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct), + ty::ConstKind::Param(param_ct) => { + param_ct.find_ty_from_env(obligation.param_env) + } }; match self.infcx.at(&obligation.cause, obligation.param_env).eq( diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 5d5a22e189c..960c27b636e 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -483,7 +483,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { let universe = self.universe_for(debruijn); let p = ty::PlaceholderConst { universe, bound: bound_const }; self.mapped_consts.insert(p, bound_const); - ty::Const::new_placeholder(self.infcx.tcx, p, ct.ty()) + ty::Const::new_placeholder(self.infcx.tcx, p) } _ => ct.super_fold_with(self), } @@ -626,7 +626,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - ty::Const::new_bound(self.infcx.tcx, db, *replace_var, ct.ty()) + ty::Const::new_bound(self.infcx.tcx, db, *replace_var) } None => { if ct.has_infer() { diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 8d7d81d8f73..ffebf7b0721 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -135,7 +135,7 @@ mod rustc { use rustc_middle::ty::ScalarInt; use rustc_span::symbol::sym; - let Ok(cv) = c.eval(tcx, param_env, DUMMY_SP) else { + let Ok((ty, cv)) = c.eval(tcx, param_env, DUMMY_SP) else { return Some(Self { alignment: true, lifetimes: true, @@ -144,7 +144,7 @@ mod rustc { }); }; - let adt_def = c.ty().ty_adt_def()?; + let adt_def = ty.ty_adt_def()?; assert_eq!( tcx.require_lang_item(LangItem::TransmuteOpts, None), diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 8a42298f216..1aec40e95f6 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -23,7 +23,7 @@ fn destructure_const<'tcx>( tcx: TyCtxt<'tcx>, const_: ty::Const<'tcx>, ) -> ty::DestructuredConst<'tcx> { - let ty::ConstKind::Value(valtree) = const_.kind() else { + let ty::ConstKind::Value(ct_ty, valtree) = const_.kind() else { bug!("cannot destructure constant {:?}", const_) }; @@ -32,7 +32,7 @@ fn destructure_const<'tcx>( _ => bug!("cannot destructure constant {:?}", const_), }; - let (fields, variant) = match const_.ty().kind() { + let (fields, variant) = match ct_ty.kind() { ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { // construct the consts for the elements of the array/slice let field_consts = branches @@ -121,7 +121,7 @@ fn recurse_build<'tcx>( let sp = node.span; match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { Ok(c) => c, - Err(LitToConstError::Reported(guar)) => ty::Const::new_error(tcx, guar, node.ty), + Err(LitToConstError::Reported(guar)) => ty::Const::new_error(tcx, guar), Err(LitToConstError::TypeError) => { bug!("encountered type error in lit_to_const") } @@ -137,35 +137,31 @@ fn recurse_build<'tcx>( } &ExprKind::NamedConst { def_id, args, user_ty: _ } => { let uneval = ty::UnevaluatedConst::new(def_id, args); - ty::Const::new_unevaluated(tcx, uneval, node.ty) + ty::Const::new_unevaluated(tcx, uneval) } - ExprKind::ConstParam { param, .. } => ty::Const::new_param(tcx, *param, node.ty), + ExprKind::ConstParam { param, .. } => ty::Const::new_param(tcx, *param), ExprKind::Call { fun, args, .. } => { + let fun_ty = body.exprs[*fun].ty; let fun = recurse_build(tcx, body, *fun, root_span)?; let mut new_args = Vec::<ty::Const<'tcx>>::with_capacity(args.len()); for &id in args.iter() { new_args.push(recurse_build(tcx, body, id, root_span)?); } - ty::Const::new_expr( - tcx, - Expr::new_call(tcx, fun.ty(), fun, new_args.into_iter()), - node.ty, - ) + ty::Const::new_expr(tcx, Expr::new_call(tcx, fun_ty, fun, new_args)) } &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { + let lhs_ty = body.exprs[lhs].ty; let lhs = recurse_build(tcx, body, lhs, root_span)?; + let rhs_ty = body.exprs[rhs].ty; let rhs = recurse_build(tcx, body, rhs, root_span)?; - ty::Const::new_expr( - tcx, - Expr::new_binop(tcx, op, lhs.ty(), rhs.ty(), lhs, rhs), - node.ty, - ) + ty::Const::new_expr(tcx, Expr::new_binop(tcx, op, lhs_ty, rhs_ty, lhs, rhs)) } &ExprKind::Unary { op, arg } if check_unop(op) => { + let arg_ty = body.exprs[arg].ty; let arg = recurse_build(tcx, body, arg, root_span)?; - ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg.ty(), arg), node.ty) + ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg_ty, arg)) } // This is necessary so that the following compiles: // @@ -187,20 +183,12 @@ fn recurse_build<'tcx>( &ExprKind::Use { source } => { let value_ty = body.exprs[source].ty; let value = recurse_build(tcx, body, source, root_span)?; - ty::Const::new_expr( - tcx, - Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty), - node.ty, - ) + ty::Const::new_expr(tcx, Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty)) } &ExprKind::Cast { source } => { let value_ty = body.exprs[source].ty; let value = recurse_build(tcx, body, source, root_span)?; - ty::Const::new_expr( - tcx, - Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty), - node.ty, - ) + ty::Const::new_expr(tcx, Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty)) } ExprKind::Borrow { arg, .. } => { let arg_node = &body.exprs[*arg]; diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 1c30f03c693..61ae36265ec 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -115,8 +115,8 @@ impl<I: Interner> CanonicalVarInfo<I> { CanonicalVarKind::PlaceholderTy(_) => false, CanonicalVarKind::Region(_) => true, CanonicalVarKind::PlaceholderRegion(..) => false, - CanonicalVarKind::Const(..) => true, - CanonicalVarKind::PlaceholderConst(_, _) => false, + CanonicalVarKind::Const(_) => true, + CanonicalVarKind::PlaceholderConst(_) => false, CanonicalVarKind::Effect => true, } } @@ -126,8 +126,8 @@ impl<I: Interner> CanonicalVarInfo<I> { CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true, CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) - | CanonicalVarKind::Const(_, _) - | CanonicalVarKind::PlaceholderConst(_, _) + | CanonicalVarKind::Const(_) + | CanonicalVarKind::PlaceholderConst(_) | CanonicalVarKind::Effect => false, } } @@ -136,12 +136,12 @@ impl<I: Interner> CanonicalVarInfo<I> { match self.kind { CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) - | CanonicalVarKind::Const(_, _) + | CanonicalVarKind::Const(_) | CanonicalVarKind::Effect => panic!("expected placeholder: {self:?}"), CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(), CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(), - CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.var().as_usize(), + CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(), } } } @@ -169,13 +169,13 @@ pub enum CanonicalVarKind<I: Interner> { PlaceholderRegion(I::PlaceholderRegion), /// Some kind of const inference variable. - Const(UniverseIndex, I::Ty), + Const(UniverseIndex), /// Effect variable `'?E`. Effect, /// A "placeholder" that represents "any const". - PlaceholderConst(I::PlaceholderConst, I::Ty), + PlaceholderConst(I::PlaceholderConst), } impl<I: Interner> PartialEq for CanonicalVarKind<I> { @@ -185,10 +185,8 @@ impl<I: Interner> PartialEq for CanonicalVarKind<I> { (Self::PlaceholderTy(l0), Self::PlaceholderTy(r0)) => l0 == r0, (Self::Region(l0), Self::Region(r0)) => l0 == r0, (Self::PlaceholderRegion(l0), Self::PlaceholderRegion(r0)) => l0 == r0, - (Self::Const(l0, l1), Self::Const(r0, r1)) => l0 == r0 && l1 == r1, - (Self::PlaceholderConst(l0, l1), Self::PlaceholderConst(r0, r1)) => { - l0 == r0 && l1 == r1 - } + (Self::Const(l0), Self::Const(r0)) => l0 == r0, + (Self::PlaceholderConst(l0), Self::PlaceholderConst(r0)) => l0 == r0, _ => std::mem::discriminant(self) == std::mem::discriminant(other), } } @@ -199,10 +197,10 @@ impl<I: Interner> CanonicalVarKind<I> { match self { CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui, CanonicalVarKind::Region(ui) => ui, - CanonicalVarKind::Const(ui, _) => ui, + CanonicalVarKind::Const(ui) => ui, CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(), CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(), - CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(), + CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(), CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => { UniverseIndex::ROOT } @@ -220,7 +218,7 @@ impl<I: Interner> CanonicalVarKind<I> { CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) } CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui), - CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty), + CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui), CanonicalVarKind::PlaceholderTy(placeholder) => { CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui)) @@ -228,8 +226,8 @@ impl<I: Interner> CanonicalVarKind<I> { CanonicalVarKind::PlaceholderRegion(placeholder) => { CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui)) } - CanonicalVarKind::PlaceholderConst(placeholder, ty) => { - CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui), ty) + CanonicalVarKind::PlaceholderConst(placeholder) => { + CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui)) } CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) | CanonicalVarKind::Effect => { @@ -345,21 +343,14 @@ impl<I: Interner> CanonicalVarValues<I> { Region::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() } - CanonicalVarKind::Effect => Const::new_anon_bound( - tcx, - ty::INNERMOST, - ty::BoundVar::from_usize(i), - Ty::new_bool(tcx), - ) - .into(), - CanonicalVarKind::Const(_, ty) - | CanonicalVarKind::PlaceholderConst(_, ty) => Const::new_anon_bound( - tcx, - ty::INNERMOST, - ty::BoundVar::from_usize(i), - ty, - ) - .into(), + CanonicalVarKind::Effect => { + Const::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) + .into() + } + CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => { + Const::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i)) + .into() + } } }, )), diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 7076df2893f..84d48e14c24 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -32,7 +32,7 @@ pub enum ConstKind<I: Interner> { Unevaluated(ty::UnevaluatedConst<I>), /// Used to hold computed value. - Value(I::ValueConst), + Value(I::Ty, I::ValueConst), /// A placeholder for a const which could not be computed; this is /// propagated to avoid useless error messages. @@ -51,7 +51,7 @@ impl<I: Interner> PartialEq for ConstKind<I> { (Bound(l0, l1), Bound(r0, r1)) => l0 == r0 && l1 == r1, (Placeholder(l0), Placeholder(r0)) => l0 == r0, (Unevaluated(l0), Unevaluated(r0)) => l0 == r0, - (Value(l0), Value(r0)) => l0 == r0, + (Value(l0, l1), Value(r0, r1)) => l0 == r0 && l1 == r1, (Error(l0), Error(r0)) => l0 == r0, (Expr(l0), Expr(r0)) => l0 == r0, _ => false, @@ -80,7 +80,7 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> { Unevaluated(uv) => { write!(f, "{:?}", &this.wrap(uv)) } - Value(valtree) => write!(f, "{valtree:?}"), + Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &this.wrap(ty)), Error(_) => write!(f, "{{const error}}"), Expr(expr) => write!(f, "{:?}", &this.wrap(expr)), } diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs index 4e8be1ee4c2..c206f3ccdb5 100644 --- a/compiler/rustc_type_ir/src/debug.rs +++ b/compiler/rustc_type_ir/src/debug.rs @@ -38,11 +38,11 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> { panic!("cannot resolve {vid:?}") } - fn opportunistic_resolve_ct_var(&self, vid: ConstVid, _: I::Ty) -> I::Const { + fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> I::Const { panic!("cannot resolve {vid:?}") } - fn opportunistic_resolve_effect_var(&self, vid: EffectVid, _: I::Ty) -> I::Const { + fn opportunistic_resolve_effect_var(&self, vid: EffectVid) -> I::Const { panic!("cannot resolve {vid:?}") } diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 501311ff72f..ee3e5ce66d0 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -387,7 +387,7 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> { match ct.kind() { ty::ConstKind::Bound(debruijn, bound_ct) if debruijn >= self.current_index => { let debruijn = debruijn.shifted_in(self.amount); - Const::new_bound(self.tcx, debruijn, bound_ct, ct.ty()) + Const::new_bound(self.tcx, debruijn, bound_ct) } _ => ct.super_fold_with(self), } diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs index bb5081fb335..24e10722448 100644 --- a/compiler/rustc_type_ir/src/infcx.rs +++ b/compiler/rustc_type_ir/src/infcx.rs @@ -12,15 +12,10 @@ pub trait InferCtxtLike { fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> <Self::Interner as Interner>::Ty; fn opportunistic_resolve_int_var(&self, vid: IntVid) -> <Self::Interner as Interner>::Ty; fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> <Self::Interner as Interner>::Ty; - fn opportunistic_resolve_ct_var( - &self, - vid: ConstVid, - ty: <Self::Interner as Interner>::Ty, - ) -> <Self::Interner as Interner>::Const; + fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> <Self::Interner as Interner>::Const; fn opportunistic_resolve_effect_var( &self, vid: EffectVid, - ty: <Self::Interner as Interner>::Ty, ) -> <Self::Interner as Interner>::Const; fn opportunistic_resolve_lt_var(&self, vid: RegionVid) -> <Self::Interner as Interner>::Region; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f305ed9b5d7..94874a6acfc 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -104,22 +104,15 @@ pub trait Const<I: Interner<Const = Self>>: + TypeSuperFoldable<I> + Flags { - fn new_infer(interner: I, var: ty::InferConst, ty: I::Ty) -> Self; + fn new_infer(interner: I, var: ty::InferConst) -> Self; - fn new_var(interner: I, var: ty::ConstVid, ty: I::Ty) -> Self; + fn new_var(interner: I, var: ty::ConstVid) -> Self; - fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst, ty: I::Ty) -> Self; + fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst) -> Self; - fn new_anon_bound( - interner: I, - debruijn: ty::DebruijnIndex, - var: ty::BoundVar, - ty: I::Ty, - ) -> Self; - - fn new_unevaluated(interner: I, uv: ty::UnevaluatedConst<I>, ty: I::Ty) -> Self; + fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self; - fn ty(self) -> I::Ty; + fn new_unevaluated(interner: I, uv: ty::UnevaluatedConst<I>) -> Self; } pub trait GenericsOf<I: Interner<GenericsOf = Self>> { diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index e7039583c91..9e0e52cfb4b 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -567,7 +567,6 @@ impl<I: Interner> AliasTerm<I> { I::Const::new_unevaluated( interner, ty::UnevaluatedConst::new(self.def_id, self.args), - interner.type_of(self.def_id).instantiate(interner, &self.args), ) .into() } |
