mirror of https://github.com/rust-lang/rust.git
Correct parent for nested anon consts
This commit is contained in:
parent
d2fb97fcec
commit
bfb7757c3c
|
@ -11,6 +11,7 @@ use rustc_session::lint;
|
||||||
use rustc_span::symbol::{kw, Symbol};
|
use rustc_span::symbol::{kw, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
|
|
||||||
|
@ -66,7 +67,22 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
// FIXME(#43408) always enable this once `lazy_normalization` is
|
// FIXME(#43408) always enable this once `lazy_normalization` is
|
||||||
// stable enough and does not need a feature gate anymore.
|
// stable enough and does not need a feature gate anymore.
|
||||||
Node::AnonConst(_) => {
|
Node::AnonConst(_) => {
|
||||||
let parent_def_id = tcx.hir().get_parent_item(hir_id);
|
let parent_did = tcx.parent(def_id.to_def_id());
|
||||||
|
|
||||||
|
// We don't do this unconditionally because the `DefId` parent of an anon const
|
||||||
|
// might be an implicitly created closure during `async fn` desugaring. This would
|
||||||
|
// have the wrong generics.
|
||||||
|
//
|
||||||
|
// i.e. `async fn foo<'a>() { let a = [(); { 1 + 2 }]; bar().await() }`
|
||||||
|
// would implicitly have a closure in its body that would be the parent of
|
||||||
|
// the `{ 1 + 2 }` anon const. This closure's generics is simply a witness
|
||||||
|
// instead of `['a]`.
|
||||||
|
let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) {
|
||||||
|
parent_did
|
||||||
|
} else {
|
||||||
|
tcx.hir().get_parent_item(hir_id).to_def_id()
|
||||||
|
};
|
||||||
|
debug!(?parent_did);
|
||||||
|
|
||||||
let mut in_param_ty = false;
|
let mut in_param_ty = false;
|
||||||
for (_parent, node) in tcx.hir().parent_iter(hir_id) {
|
for (_parent, node) in tcx.hir().parent_iter(hir_id) {
|
||||||
|
@ -121,7 +137,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
//
|
//
|
||||||
// This has some implications for how we get the predicates available to the anon const
|
// This has some implications for how we get the predicates available to the anon const
|
||||||
// see `explicit_predicates_of` for more information on this
|
// see `explicit_predicates_of` for more information on this
|
||||||
let generics = tcx.generics_of(parent_def_id.to_def_id());
|
let generics = tcx.generics_of(parent_did);
|
||||||
let param_def_idx = generics.param_def_id_to_index[¶m_id.to_def_id()];
|
let param_def_idx = generics.param_def_id_to_index[¶m_id.to_def_id()];
|
||||||
// In the above example this would be .params[..N#0]
|
// In the above example this would be .params[..N#0]
|
||||||
let own_params = generics.params_to(param_def_idx as usize, tcx).to_owned();
|
let own_params = generics.params_to(param_def_idx as usize, tcx).to_owned();
|
||||||
|
@ -147,7 +163,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
//
|
//
|
||||||
// Note that we do not supply the parent generics when using
|
// Note that we do not supply the parent generics when using
|
||||||
// `min_const_generics`.
|
// `min_const_generics`.
|
||||||
Some(parent_def_id.to_def_id())
|
Some(parent_did)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let parent_node = tcx.parent_hir_node(hir_id);
|
let parent_node = tcx.parent_hir_node(hir_id);
|
||||||
|
@ -159,7 +175,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
|
Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
|
||||||
if constant.hir_id() == hir_id =>
|
if constant.hir_id() == hir_id =>
|
||||||
{
|
{
|
||||||
Some(parent_def_id.to_def_id())
|
Some(parent_did)
|
||||||
}
|
}
|
||||||
// Exclude `GlobalAsm` here which cannot have generics.
|
// Exclude `GlobalAsm` here which cannot have generics.
|
||||||
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
||||||
|
@ -171,7 +187,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
_ => false,
|
_ => false,
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
Some(parent_def_id.to_def_id())
|
Some(parent_did)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Given an anon const `a`: `{ N }` and some anon const `b` which references the
|
||||||
|
// first anon const: `{ [1; a] }`. `b` should not have any generics as it is not
|
||||||
|
// a simple `N` argument nor is it a repeat expr count.
|
||||||
|
//
|
||||||
|
// On the other hand `b` *is* a repeat expr count and so it should inherit its
|
||||||
|
// parents generics as part of the `const_evaluatable_unchecked` fcw (#76200).
|
||||||
|
//
|
||||||
|
// In this specific case however `b`'s parent should be `a` and so it should wind
|
||||||
|
// up not having any generics after all. If `a` were to inherit its generics from
|
||||||
|
// the enclosing item then the reference to `a` from `b` would contain generic
|
||||||
|
// parameters not usable by `b` which would cause us to ICE.
|
||||||
|
|
||||||
|
fn bar<const N: usize>() {}
|
||||||
|
|
||||||
|
fn foo<const N: usize>() {
|
||||||
|
bar::<{ [1; N] }>();
|
||||||
|
//~^ ERROR: generic parameters may not be used in const operations
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
error: generic parameters may not be used in const operations
|
||||||
|
--> $DIR/repeat_expr_hack_gives_right_generics.rs:16:17
|
||||||
|
|
|
||||||
|
LL | bar::<{ [1; N] }>();
|
||||||
|
| ^ cannot perform const operation using `N`
|
||||||
|
|
|
||||||
|
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||||
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Reference in New Issue