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

`}

`