Auto merge of #3630 - rust-lang:rustup-2024-05-25, r=saethlin · rust-lang/rust@331bb3f (original) (raw)
`@@ -461,83 +461,55 @@ pub(super) fn explicit_predicates_of<'tcx>(
`
461
461
`}
`
462
462
`}
`
463
463
`} else {
`
464
``
`-
if matches!(def_kind, DefKind::AnonConst) && tcx.features().generic_const_exprs {
`
465
``
`-
let hir_id = tcx.local_def_id_to_hir_id(def_id);
`
466
``
`-
let parent_def_id = tcx.hir().get_parent_item(hir_id);
`
467
``
-
468
``
`-
if let Some(defaulted_param_def_id) =
`
469
``
`-
tcx.hir().opt_const_param_default_param_def_id(hir_id)
`
470
``
`-
{
`
471
``
`` -
// In generics_of
we set the generics' parent to be our parent's parent which means that
``
472
``
`-
// we lose out on the predicates of our actual parent if we dont return those predicates here.
`
473
``
`` -
// (See comment in generics_of
for more information on why the parent shenanigans is necessary)
``
474
``
`-
//
`
475
``
`-
// struct Foo<T, const N: usize = { ::ASSOC }>(T) where T: Trait;
`
476
``
`-
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
`
477
``
`-
// ^^^ explicit_predicates_of on
`
478
``
`-
// parent item we dont have set as the
`
479
``
`` -
// parent of generics returned by generics_of
``
480
``
`-
//
`
481
``
`` -
// In the above code we want the anon const to have predicates in its param env for T: Trait
``
482
``
`` -
// and we would be calling explicit_predicates_of(Foo)
here
``
483
``
`-
let parent_preds = tcx.explicit_predicates_of(parent_def_id);
`
484
``
-
485
``
`` -
// If we dont filter out ConstArgHasType
predicates then every single defaulted const parameter
``
486
``
`-
// will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
`
487
``
`-
// to #106994 is implemented.
`
488
``
`-
let filtered_predicates = parent_preds
`
489
``
`-
.predicates
`
490
``
`-
.into_iter()
`
491
``
`-
.filter(|(pred, _)| {
`
492
``
`-
if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
`
493
``
`-
match ct.kind() {
`
494
``
`-
ty::ConstKind::Param(param_const) => {
`
495
``
`-
let defaulted_param_idx = tcx
`
496
``
`-
.generics_of(parent_def_id)
`
497
``
`-
.param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
`
498
``
`-
param_const.index < defaulted_param_idx
`
499
``
`-
}
`
500
``
`-
_ => bug!(
`
501
``
`` -
"ConstArgHasType
in predicates_of
\
``
502
``
`` -
that isn't a Param
const"
``
503
``
`-
),
`
``
464
`+
if matches!(def_kind, DefKind::AnonConst)
`
``
465
`+
&& tcx.features().generic_const_exprs
`
``
466
`+
&& let Some(defaulted_param_def_id) =
`
``
467
`+
tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
`
``
468
`+
{
`
``
469
`` +
// In generics_of
we set the generics' parent to be our parent's parent which means that
``
``
470
`+
// we lose out on the predicates of our actual parent if we dont return those predicates here.
`
``
471
`` +
// (See comment in generics_of
for more information on why the parent shenanigans is necessary)
``
``
472
`+
//
`
``
473
`+
// struct Foo<T, const N: usize = { ::ASSOC }>(T) where T: Trait;
`
``
474
`+
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
`
``
475
`+
// ^^^ explicit_predicates_of on
`
``
476
`+
// parent item we dont have set as the
`
``
477
`` +
// parent of generics returned by generics_of
``
``
478
`+
//
`
``
479
`` +
// In the above code we want the anon const to have predicates in its param env for T: Trait
``
``
480
`` +
// and we would be calling explicit_predicates_of(Foo)
here
``
``
481
`+
let parent_def_id = tcx.local_parent(def_id);
`
``
482
`+
let parent_preds = tcx.explicit_predicates_of(parent_def_id);
`
``
483
+
``
484
`` +
// If we dont filter out ConstArgHasType
predicates then every single defaulted const parameter
``
``
485
`+
// will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
`
``
486
`+
// to #106994 is implemented.
`
``
487
`+
let filtered_predicates = parent_preds
`
``
488
`+
.predicates
`
``
489
`+
.into_iter()
`
``
490
`+
.filter(|(pred, _)| {
`
``
491
`+
if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
`
``
492
`+
match ct.kind() {
`
``
493
`+
ty::ConstKind::Param(param_const) => {
`
``
494
`+
let defaulted_param_idx = tcx
`
``
495
`+
.generics_of(parent_def_id)
`
``
496
`+
.param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
`
``
497
`+
param_const.index < defaulted_param_idx
`
504
498
`}
`
505
``
`-
} else {
`
506
``
`-
true
`
``
499
`+
_ => bug!(
`
``
500
`` +
"ConstArgHasType
in predicates_of
\
``
``
501
`` +
that isn't a Param
const"
``
``
502
`+
),
`
507
503
`}
`
508
``
`-
})
`
509
``
`-
.cloned();
`
510
``
`-
return GenericPredicates {
`
511
``
`-
parent: parent_preds.parent,
`
512
``
`-
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
`
513
``
`-
};
`
514
``
`-
}
`
515
``
-
516
``
`-
let parent_def_kind = tcx.def_kind(parent_def_id);
`
517
``
`-
if matches!(parent_def_kind, DefKind::OpaqueTy) {
`
518
``
`` -
// In instantiate_identity
we inherit the predicates of our parent.
``
519
``
`` -
// However, opaque types do not have a parent (see gather_explicit_predicates_of
), which means
``
520
``
`-
// that we lose out on the predicates of our actual parent if we dont return those predicates here.
`
521
``
`-
//
`
522
``
`-
//
`
523
``
`-
// fn foo<T: Trait>() -> impl Iterator<Output = Another<{ ::ASSOC }> > { todo!() }
`
524
``
`-
// ^^^^^^^^^^^^^^^^^^^ the def id we are calling
`
525
``
`-
// explicit_predicates_of on
`
526
``
`-
//
`
527
``
`` -
// In the above code we want the anon const to have predicates in its param env for T: Trait
.
``
528
``
`-
// However, the anon const cannot inherit predicates from its parent since it's opaque.
`
529
``
`-
//
`
530
``
`` -
// To fix this, we call explicit_predicates_of
directly on foo
, the parent's parent.
``
531
``
-
532
``
`` -
// In the above example this is foo::{opaque#0}
or impl Iterator
``
533
``
`-
let parent_hir_id = tcx.local_def_id_to_hir_id(parent_def_id.def_id);
`
534
``
-
535
``
`` -
// In the above example this is the function foo
``
536
``
`-
let item_def_id = tcx.hir().get_parent_item(parent_hir_id);
`
537
``
-
538
``
`` -
// In the above code example we would be calling explicit_predicates_of(foo)
here
``
539
``
`-
return tcx.explicit_predicates_of(item_def_id);
`
540
``
`-
}
`
``
504
`+
} else {
`
``
505
`+
true
`
``
506
`+
}
`
``
507
`+
})
`
``
508
`+
.cloned();
`
``
509
`+
return GenericPredicates {
`
``
510
`+
parent: parent_preds.parent,
`
``
511
`+
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
`
``
512
`+
};
`
541
513
`}
`
542
514
`gather_explicit_predicates_of(tcx, def_id)
`
543
515
`}
`