diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index d637f51649631..c5c0f19038be9 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -116,13 +116,13 @@ pub(crate) fn codegen_constant<'tcx>( let const_ = fx.monomorphize(constant.literal); let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { - assert!(substs.is_empty()); - assert!(promoted.is_none()); + ConstKind::Unevaluated(uv) if fx.tcx.is_static(uv.def.did) => { + assert!(uv.substs(fx.tcx).is_empty()); + assert!(uv.promoted.is_none()); return codegen_static_ref( fx, - def.did, + uv.def.did, fx.layout_of(fx.monomorphize(&constant.literal.ty)), ) .to_cvalue(fx); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 7b18f4d0ff6a9..e7c078937d1b4 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1498,16 +1498,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, - ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>, + unevaluated: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { let mut original_values = OriginalQueryValues::default(); - let canonical = self.canonicalize_query((param_env, substs), &mut original_values); + let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values); - let (param_env, substs) = canonical.value; + let (param_env, unevaluated) = canonical.value; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. - self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span) + self.tcx.const_eval_resolve(param_env, unevaluated, span) } /// If `typ` is a type variable of some kind, resolve it one level diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index fa7c0670e8ce6..c63613ae3af29 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> { ct: ty::Unevaluated<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { + match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs(self)) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: ct.promoted }; self.const_eval_global_id(param_env, cid, span) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b03b26d64606c..1c733eceb92be 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -93,6 +93,10 @@ rustc_queries! { desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) } } + query default_anon_const_substs(key: DefId) -> SubstsRef<'tcx> { + desc { |tcx| "computing the default generic arguments for `{}`", tcx.def_path_str(key) } + } + /// Records the type of every item. query type_of(key: DefId) -> Ty<'tcx> { desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d078e73897161..1b0fa31b302a0 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,6 +1,5 @@ use crate::mir::interpret::ConstValue; use crate::mir::interpret::{LitToConstInput, Scalar}; -use crate::ty::subst::InternalSubsts; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{ParamEnv, ParamEnvAnd}; use rustc_errors::ErrorReported; @@ -98,7 +97,7 @@ impl<'tcx> Const<'tcx> { } _ => ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), + non_default_substs: None, promoted: None, }), }; diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index b4c38bfbb461d..f934f721cdedc 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -14,10 +14,16 @@ use rustc_target::abi::Size; #[derive(Hash, HashStable)] pub struct Unevaluated<'tcx> { pub def: ty::WithOptConstParam, - pub substs: SubstsRef<'tcx>, + pub non_default_substs: Option>, pub promoted: Option, } +impl<'tcx> Unevaluated<'tcx> { + pub fn substs(self, tcx: TyCtxt<'tcx>) -> SubstsRef<'tcx> { + self.non_default_substs.unwrap_or_else(|| tcx.default_anon_const_substs(self.def.did)) + } +} + /// Represents a constant in Rust. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Hash, HashStable)] @@ -102,7 +108,7 @@ impl<'tcx> ConstKind<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option, ErrorReported>> { - if let ConstKind::Unevaluated(Unevaluated { def, substs, promoted }) = self { + if let ConstKind::Unevaluated(unevaluated) = self { use crate::mir::interpret::ErrorHandled; // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` @@ -111,29 +117,35 @@ impl<'tcx> ConstKind<'tcx> { // Note that we erase regions *before* calling `with_reveal_all_normalized`, // so that we don't try to invoke this query with // any region variables. - let param_env_and_substs = tcx + let param_env_and = tcx .erase_regions(param_env) .with_reveal_all_normalized(tcx) - .and(tcx.erase_regions(substs)); + .and(tcx.erase_regions(unevaluated)); // HACK(eddyb) when the query key would contain inference variables, // attempt using identity substs and `ParamEnv` instead, that will succeed // when the expression doesn't depend on any parameters. // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that // we can call `infcx.const_eval_resolve` which handles inference variables. - let param_env_and_substs = if param_env_and_substs.needs_infer() { - tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did)) + let param_env_and = if param_env_and.needs_infer() { + tcx.param_env(unevaluated.def.did).and(ty::Unevaluated { + def: unevaluated.def, + non_default_substs: Some(InternalSubsts::identity_for_item( + tcx, + unevaluated.def.did, + )), + promoted: unevaluated.promoted, + }) } else { - param_env_and_substs + param_env_and }; // FIXME(eddyb) maybe the `const_eval_*` methods should take - // `ty::ParamEnvAnd` instead of having them separate. - let (param_env, substs) = param_env_and_substs.into_parts(); + // `ty::ParamEnvAnd` instead of having them separate. + let (param_env, unevaluated) = param_env_and.into_parts(); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None) - { + match tcx.const_eval_resolve(param_env, unevaluated, None) { // NOTE(eddyb) `val` contains no lifetimes/types/consts, // and we use the original type, so nothing from `substs` // (which may be identity substs, see above), diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index d6dc81c5b785d..78369676bc494 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -295,7 +295,8 @@ impl FlagComputation { } fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) { - self.add_substs(ct.substs); + // TODO + self.add_substs(ct.non_default_substs.unwrap()); self.add_flags(TypeFlags::HAS_CT_PROJECTION); } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a97c6bf4f9a53..d0a2d104afa59 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -915,7 +915,9 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs, promoted }) => { + // TODO + let substs = non_default_substs.unwrap(); if let Some(promoted) = promoted { p!(print_value_path(def.did, substs)); p!(write("::{:?}", promoted)); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index e54e44a6157e8..678ec2354c894 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -590,7 +590,7 @@ pub fn super_relate_consts>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => { - if tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) { + if tcx.try_unify_abstract_consts(((au.def, au.substs(tcx)), (bu.def, bu.substs(tcx)))) { Ok(a.val) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) @@ -603,11 +603,14 @@ pub fn super_relate_consts>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def && au.promoted == bu.promoted => { - let substs = - relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?; + let substs = relation.relate_with_variance( + ty::Variance::Invariant, + au.substs(tcx), + bu.substs(tcx), + )?; Ok(ty::ConstKind::Unevaluated(ty::Unevaluated { def: au.def, - substs, + non_default_substs: Some(substs), promoted: au.promoted, })) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 2da23b331e0cb..c7a217c5dde97 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1031,13 +1031,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - ty::ConstKind::Unevaluated(ty::Unevaluated { - def, - substs: substs.fold_with(folder), - promoted, - }) - } + ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) @@ -1049,7 +1043,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), - ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor), + ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) @@ -1067,3 +1061,17 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { ControlFlow::CONTINUE } } + +impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { + fn super_fold_with>(self, folder: &mut F) -> Self { + ty::Unevaluated { + def: self.def, + non_default_substs: Some(self.substs(folder.tcx()).fold_with(folder)), + promoted: self.promoted, + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.substs(visitor.tcx_for_anon_const_substs()).visit_with(visitor) + } +} diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index c2fe5f1ef3f62..721c96503d140 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -196,7 +196,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Error(_) => {} ty::ConstKind::Unevaluated(ct) => { - stack.extend(ct.substs.iter().rev()); + // TODO + stack.extend(ct.non_default_substs.unwrap().iter().rev()); } } } diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index 157adf8438488..f3f0fb5274da7 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -314,10 +314,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else { let tcx = self.tcx(); - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) = - constant.literal.val - { - if let Some(promoted) = promoted { + if let ty::ConstKind::Unevaluated(uv) = constant.literal.val { + if let Some(promoted) = uv.promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, promoted: &Body<'tcx>, ty, @@ -352,8 +350,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ConstraintCategory::Boring, self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty, - def.did, - UserSubsts { substs, user_self_ty: None }, + uv.def.did, + UserSubsts { substs: uv.substs(tcx), user_self_ty: None }, )), ) { span_mirbug!( diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 93e294651cbaa..b7b5ca3cfc6fd 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -566,9 +566,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val_val = match val.val { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)), - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - let instance = self.resolve(def, substs)?; - return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); + ty::ConstKind::Unevaluated(uv) => { + let instance = self.resolve(uv.def, uv.substs(*self.tcx))?; + return Ok(self + .eval_to_allocation(GlobalId { instance, promoted: uv.promoted })? + .into()); } ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => { span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val) diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index f2e1034f6a321..2f96441b2e044 100644 --- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs @@ -302,21 +302,24 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)}) + ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs: _, promoted: Some(p)}) // Avoid considering `T` unused when constants are of the form: // `>::foo::promoted[p]` if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self => { // If there is a promoted, don't look at the substs - since it will always contain // the generic parameters, instead, traverse the promoted MIR. + // + // FIXME(lcnr): This seems incorrect if we get the promoted by inlining. + // We have to consider its substs in that case. let promoted = self.tcx.promoted_mir(def.did); self.visit_body(&promoted[p]); ControlFlow::CONTINUE } - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) - if self.tcx.def_kind(def.did) == DefKind::AnonConst => + ty::ConstKind::Unevaluated(uv) + if self.tcx.def_kind(uv.def.did) == DefKind::AnonConst => { - self.visit_child_body(def.did, substs); + self.visit_child_body(uv.def.did, uv.substs(self.tcx)); ControlFlow::CONTINUE } _ => c.super_visit_with(self), diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index c8dce55f69a1a..35351f60a0f11 100644 --- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs @@ -246,7 +246,7 @@ where }; // Check the qualifs of the value of `const` items. - if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = + if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs: _, promoted }) = constant.literal.val { assert!(promoted.is_none()); diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index 4be8b42993e69..3a8896faa913d 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -1002,13 +1002,17 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { ty, val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, - substs: InternalSubsts::for_item(tcx, def.did, |param, _| { - if let ty::GenericParamDefKind::Lifetime = param.kind { - tcx.lifetimes.re_erased.into() - } else { - tcx.mk_param_from_def(param) - } - }), + non_default_substs: Some(InternalSubsts::for_item( + tcx, + def.did, + |param, _| { + if let ty::GenericParamDefKind::Lifetime = param.kind { + tcx.lifetimes.re_erased.into() + } else { + tcx.mk_param_from_def(param) + } + }, + )), promoted: Some(promoted_id), }), }), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index df2f9c8581f37..8ac38dec0a4e3 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -694,7 +694,7 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> { let lhs = mk_const(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(did), - substs, + non_default_substs: Some(substs), promoted: None, }), ty: var_ty, @@ -892,7 +892,7 @@ impl<'thir, 'tcx> Cx<'thir, 'tcx> { literal: self.tcx.mk_const(ty::Const { val: ty::ConstKind::Unevaluated(ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id), - substs, + non_default_substs: Some(substs), promoted: None, }), ty: self.typeck_results().node_type(expr.hir_id), diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index d5ef72741c4b7..17fea6ba4fe44 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -165,7 +165,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( // See #74595 for more details about this. let concrete = infcx.const_eval_resolve( param_env, - ty::Unevaluated { def, substs, promoted: None }, + ty::Unevaluated { def, non_default_substs: Some(substs), promoted: None }, Some(span), ); @@ -243,9 +243,7 @@ impl AbstractConst<'tcx> { ct: &ty::Const<'tcx>, ) -> Result>, ErrorReported> { match ct.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => { - AbstractConst::new(tcx, def, substs) - } + ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.def, uv.substs(tcx)), ty::ConstKind::Error(_) => Err(ErrorReported), _ => Ok(None), } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index a383658684d59..e5879561f3b30 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -511,7 +511,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ty::PredicateKind::ConstEquate(c1, c2) => { debug!(?c1, ?c2, "equating consts"); - if self.selcx.tcx().features().const_evaluatable_checked { + let tcx = self.selcx.tcx(); + if tcx.features().const_evaluatable_checked { // FIXME: we probably should only try to unify abstract constants // if the constants depend on generic parameters. // @@ -519,11 +520,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = (c1.val, c2.val) { - if self - .selcx - .tcx() - .try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs))) - { + if tcx.try_unify_abstract_consts(( + (a.def, a.substs(tcx)), + (b.def, b.substs(tcx)), + )) { return ProcessResult::Changed(vec![]); } } @@ -542,7 +542,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { Err(ErrorHandled::TooGeneric) => { stalled_on.extend( unevaluated - .substs + .substs(tcx) .iter() .filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index aee128dec7d12..7c4f4ab7ed676 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -430,13 +430,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => { - assert!(promoted.is_none()); + ty::ConstKind::Unevaluated(uv) => { + assert!(uv.promoted.is_none()); + let substs = uv.substs(self.tcx()); - let obligations = self.nominal_obligations(def.did, substs); + let obligations = self.nominal_obligations(uv.def.did, substs); self.out.extend(obligations); - let predicate = ty::PredicateKind::ConstEvaluatable(def, substs) + let predicate = ty::PredicateKind::ConstEvaluatable(uv.def, substs) .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::with_depth( diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index d4668de2b9f8c..25bd81b5e5b51 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -69,6 +69,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { pub fn provide(providers: &mut Providers) { *providers = Providers { opt_const_param_of: type_of::opt_const_param_of, + default_anon_const_substs: type_of::default_anon_const_substs, type_of: type_of::type_of, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, @@ -2204,7 +2205,8 @@ fn const_evaluatable_predicates_of<'tcx>( assert_eq!(uv.promoted, None); let span = self.tcx.hir().span(c.hir_id); self.preds.insert(( - ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs).to_predicate(self.tcx), + ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs(self.tcx)) + .to_predicate(self.tcx), span, )); } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 3f2f244e44fd2..285e20c7ac2af 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -7,7 +7,7 @@ use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, Node}; use rustc_middle::hir::map::Map; -use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; +use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::Ident; @@ -250,6 +250,10 @@ fn get_path_containing_arg_in_pat<'hir>( arg_path } +pub(super) fn default_anon_const_substs(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { + InternalSubsts::identity_for_item(tcx, def_id) +} + pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let def_id = def_id.expect_local(); use rustc_hir::*; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 6f283d501a4f2..c9c0e5e332b89 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -296,7 +296,7 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => { + ty::ConstKind::Unevaluated(ty::Unevaluated { def, non_default_substs: _, promoted }) => { let mut s = if let Some(def) = def.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did); print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id)) diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 3e1db233696fe..68d921044fc8d 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -185,7 +185,7 @@ fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: D cx.param_env, ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id), - substs, + non_default_substs: Some(substs), promoted: None }, None diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index ebe896b7ae867..4199abc54eab8 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -343,7 +343,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { self.param_env, ty::Unevaluated { def: ty::WithOptConstParam::unknown(def_id), - substs, + non_default_substs: Some(substs), promoted: None, }, None,