Skip to content

Commit

Permalink
effects: support ~const in assoc fns in trait impls
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Jan 7, 2024
1 parent 8d39ec1 commit 3acc5a0
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 30 deletions.
29 changes: 16 additions & 13 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand Down
37 changes: 20 additions & 17 deletions tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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::<()>();
}

0 comments on commit 3acc5a0

Please sign in to comment.