effects: support ~const in assoc fns in trait impls

This commit is contained in:
León Orell Valerian Liehr 2024-01-07 18:22:47 +01:00
parent 8d39ec1825
commit 3acc5a0da3
No known key found for this signature in database
GPG Key ID: D17A07215F68E713
4 changed files with 65 additions and 30 deletions

View File

@ -12,6 +12,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_hir::PredicateOrigin;
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, sym, Ident};
@ -572,23 +573,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
// This is used to track which lifetimes have already been defined,
// and which need to be replicated when lowering an async fn.
match parent_hir.node().expect_item().kind {
let generics = match parent_hir.node().expect_item().kind {
hir::ItemKind::Impl(impl_) => {
self.is_in_trait_impl = impl_.of_trait.is_some();
&impl_.generics
}
hir::ItemKind::Trait(_, _, generics, _, _) if self.tcx.features().effects => {
self.host_param_id = generics
.params
.iter()
.find(|param| {
matches!(
param.kind,
hir::GenericParamKind::Const { is_host_effect: true, .. }
)
})
.map(|param| param.def_id);
hir::ItemKind::Trait(_, _, generics, _, _) => generics,
kind => {
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
}
_ => {}
};
if self.tcx.features().effects {
self.host_param_id = generics
.params
.iter()
.find(|param| {
matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })
})
.map(|param| param.def_id);
}
match ctxt {

View File

@ -1,27 +1,30 @@
error[E0277]: can't compare `impl PartialEq + Destruct + Copy` with `impl PartialEq + Destruct + Copy`
--> $DIR/const-impl-trait.rs:28:17
error[E0277]: can't compare `()` with `()`
--> $DIR/const-impl-trait.rs:35:17
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `impl PartialEq + Destruct + Copy == impl PartialEq + Destruct + Copy`
LL | assert!(cmp(&()));
| --- ^^^ no implementation for `() == ()`
| |
| required by a bound introduced by this call
|
= help: the trait `~const PartialEq` is not implemented for `impl PartialEq + Destruct + Copy`
note: required by a bound in `Foo::{opaque#0}`
--> $DIR/const-impl-trait.rs:24:22
= help: the trait `const PartialEq` is not implemented for `()`
= help: the trait `PartialEq` is implemented for `()`
note: required by a bound in `cmp`
--> $DIR/const-impl-trait.rs:12:23
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
| ^^^^^^^^^^^^^^^^ required by this bound in `cmp`
error[E0277]: can't drop `impl PartialEq + Destruct + Copy`
--> $DIR/const-impl-trait.rs:28:17
error[E0277]: can't compare `&impl ~const PartialEq` with `&impl ~const PartialEq`
--> $DIR/const-impl-trait.rs:13:7
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `impl PartialEq + Destruct + Copy`
LL | a == a
| ^^ no implementation for `&impl ~const PartialEq == &impl ~const PartialEq`
|
note: required by a bound in `Foo::{opaque#0}`
--> $DIR/const-impl-trait.rs:24:41
= help: the trait `~const PartialEq<&impl ~const PartialEq>` is not implemented for `&impl ~const PartialEq`
help: consider dereferencing both sides of the expression
|
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
| ^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
LL | *a == *a
| + +
error: aborting due to 2 previous errors

View File

@ -0,0 +1,29 @@
// Regression test for issue #119700.
// check-pass
#![feature(const_trait_impl, effects)]
#[const_trait]
trait Main {
fn compute<T: ~const Aux>() -> u32;
}
impl const Main for () {
fn compute<T: ~const Aux>() -> u32 {
T::generate()
}
}
#[const_trait]
trait Aux {
fn generate() -> u32;
}
impl const Aux for () {
fn generate() -> u32 { 1024 }
}
fn main() {
const _: u32 = <()>::compute::<()>();
let _ = <()>::compute::<()>();
}