From 05dcb7874a5a8c84fe943dcbae12010ba5a40c25 Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 23 Jun 2021 18:18:32 +0100 Subject: [PATCH] Dont provide all parent generics to cgdefaults --- compiler/rustc_middle/src/ty/consts.rs | 33 +++++++++++++++++-- .../defaults/cec-build-subst-ice.rs | 10 ++++++ .../defaults/cec-build-subst-ice.stderr | 12 +++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/const-generics/defaults/cec-build-subst-ice.rs create mode 100644 src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index c78151271c1..16ec935ba1a 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -85,7 +85,10 @@ impl<'tcx> Const<'tcx> { _ => expr, }; - use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath}; + use hir::{ + def::DefKind::ConstParam, def::Res, ExprKind, GenericParam, GenericParamKind, Node, + Path, QPath, + }; let val = match expr.kind { ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => { // Find the name and index of the const parameter by indexing the generics of @@ -100,7 +103,33 @@ impl<'tcx> Const<'tcx> { } _ => ty::ConstKind::Unevaluated(ty::Unevaluated { def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), + substs: { + let ct_hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let parent_id = tcx.hir().get_parent_node(ct_hir_id); + match tcx.hir().get(parent_id) { + // If this anon ct is a cg default we should only provide non-fwd declared params + // https://github.com/rust-lang/rust/issues/83938 + Node::GenericParam(GenericParam { + hir_id: param_id, + kind: GenericParamKind::Const { .. }, + .. + }) => { + let item_id = tcx.hir().get_parent_node(*param_id); + let item_def_id = tcx.hir().local_def_id(item_id); + let generics = tcx.generics_of(item_def_id.to_def_id()); + let param_def = tcx.hir().local_def_id(*param_id).to_def_id(); + let param_def_idx = generics.param_def_id_to_index[¶m_def]; + let substs = generics + .params + .iter() + .map(|param| tcx.mk_param_from_def(param)) + .take(param_def_idx as usize) + .collect::>(); + tcx.intern_substs(&substs) + } + _ => InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), + } + }, promoted: None, }), }; diff --git a/src/test/ui/const-generics/defaults/cec-build-subst-ice.rs b/src/test/ui/const-generics/defaults/cec-build-subst-ice.rs new file mode 100644 index 00000000000..d43e136d574 --- /dev/null +++ b/src/test/ui/const-generics/defaults/cec-build-subst-ice.rs @@ -0,0 +1,10 @@ +#![feature(const_evaluatable_checked, const_generics, const_generics_defaults)] +#![allow(incomplete_features)] + +pub struct Bar; +pub fn foo() -> Bar { + loop {} +} +//~^ error: unconstrained generic constant + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr b/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr new file mode 100644 index 00000000000..0508007412c --- /dev/null +++ b/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr @@ -0,0 +1,12 @@ +error: unconstrained generic constant + --> $DIR/cec-build-subst-ice.rs:5:34 + | +LL | pub struct Bar; + | --------- required by this bound in `Bar` +LL | pub fn foo() -> Bar { loop {} } + | ^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:` + +error: aborting due to previous error +