Moves changes to explicit_preds_of/inferred_outlives_of/generics_of
This commit is contained in:
parent
05dcb7874a
commit
b44be27999
4 changed files with 71 additions and 33 deletions
|
@ -85,10 +85,7 @@ impl<'tcx> Const<'tcx> {
|
|||
_ => expr,
|
||||
};
|
||||
|
||||
use hir::{
|
||||
def::DefKind::ConstParam, def::Res, ExprKind, GenericParam, GenericParamKind, Node,
|
||||
Path, QPath,
|
||||
};
|
||||
use hir::{def::DefKind::ConstParam, def::Res, ExprKind, 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
|
||||
|
@ -103,33 +100,7 @@ impl<'tcx> Const<'tcx> {
|
|||
}
|
||||
_ => ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||
def: def.to_global(),
|
||||
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::<smallvec::SmallVec<[_; 8]>>();
|
||||
tcx.intern_substs(&substs)
|
||||
}
|
||||
_ => InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
}
|
||||
},
|
||||
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
promoted: None,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -1441,6 +1441,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
|||
// of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
|
||||
None
|
||||
} else if tcx.lazy_normalization() {
|
||||
// Only provide backwards declared generics to cg defaults (#83938)
|
||||
if let Node::GenericParam(GenericParam {
|
||||
hir_id: param_id,
|
||||
kind: GenericParamKind::Const { .. },
|
||||
..
|
||||
}) = tcx.hir().get(tcx.hir().get_parent_node(hir_id))
|
||||
{
|
||||
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 params = generics.params[..param_def_idx as usize].to_owned();
|
||||
let param_def_id_to_index =
|
||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||
|
||||
return ty::Generics {
|
||||
parent: generics.parent,
|
||||
parent_count: generics.parent_count,
|
||||
params,
|
||||
param_def_id_to_index,
|
||||
has_self: generics.has_self,
|
||||
has_late_bound_regions: generics.has_late_bound_regions,
|
||||
};
|
||||
}
|
||||
|
||||
// HACK(eddyb) this provides the correct generics when
|
||||
// `feature(const_generics)` is enabled, so that const expressions
|
||||
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
||||
|
@ -2359,7 +2385,8 @@ fn trait_explicit_predicates_and_bounds(
|
|||
}
|
||||
|
||||
fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
|
||||
if let DefKind::Trait = tcx.def_kind(def_id) {
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
if let DefKind::Trait = def_kind {
|
||||
// Remove bounds on associated types from the predicates, they will be
|
||||
// returned by `explicit_item_bounds`.
|
||||
let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local());
|
||||
|
@ -2404,6 +2431,21 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
|
||||
// Provide predicates of parent item of cg defaults manually
|
||||
// as generics_of doesn't return a parent for the generics
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
if let Node::GenericParam(hir::GenericParam {
|
||||
hir_id: param_id,
|
||||
kind: hir::GenericParamKind::Const { .. },
|
||||
..
|
||||
}) = tcx.hir().get(tcx.hir().get_parent_node(hir_id))
|
||||
{
|
||||
let item_id = tcx.hir().get_parent_node(*param_id);
|
||||
let item_def_id = tcx.hir().local_def_id(item_id).to_def_id();
|
||||
return tcx.explicit_predicates_of(item_def_id);
|
||||
}
|
||||
}
|
||||
gather_explicit_predicates_of(tcx, def_id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,22 @@ pub fn provide(providers: &mut Providers) {
|
|||
fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate<'_>, Span)] {
|
||||
let id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local());
|
||||
|
||||
if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst) && tcx.lazy_normalization()
|
||||
{
|
||||
// Provide inferred outlive preds of parent item of cg defaults manually
|
||||
// as generics_of doesn't return a parent for the generics
|
||||
if let Node::GenericParam(hir::GenericParam {
|
||||
hir_id: param_id,
|
||||
kind: hir::GenericParamKind::Const { .. },
|
||||
..
|
||||
}) = tcx.hir().get(tcx.hir().get_parent_node(id))
|
||||
{
|
||||
let item_id = tcx.hir().get_parent_node(*param_id);
|
||||
let item_def_id = tcx.hir().local_def_id(item_id).to_def_id();
|
||||
return tcx.inferred_outlives_of(item_def_id);
|
||||
}
|
||||
}
|
||||
|
||||
match tcx.hir().get(id) {
|
||||
Node::Item(item) => match item.kind {
|
||||
hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
|
||||
|
|
|
@ -8,5 +8,14 @@ LL | pub fn foo<const N1: usize>() -> Bar<N1> { loop {} }
|
|||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:`
|
||||
|
||||
error: aborting due to previous error
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/cec-build-subst-ice.rs:15:8
|
||||
|
|
||||
LL | type Alias<T, const N: usize, const NP: usize = {N+1usize}> = [T; NP];
|
||||
| ---------- required by this bound in `Alias::{constant#0}`
|
||||
LL | fn alias<T, const N: usize>(_: [T; N], _: T)
|
||||
LL | -> Alias<T, N>
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); {N+1usize}]:`
|
||||
|
||||
|
|
Loading…
Reference in a new issue