diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 0b81f4693712f..d3ff1f7bebe65 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -371,10 +371,9 @@ pub(super) fn explicit_item_bounds_with_filter( associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter); return ty::EarlyBinder::bind(bounds); } - Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!( - tcx.def_span(def_id), - "item bounds for RPITIT in impl to be fed on def-id creation" - ), + Some(ty::ImplTraitInTraitData::Impl { .. }) => { + span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds") + } None => {} } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ca2597e79fd14..698aa9fa0e60e 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -950,6 +950,15 @@ pub(super) fn const_conditions<'tcx>( bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}"); } + match tcx.opt_rpitit_info(def_id.to_def_id()) { + // RPITITs inherit const conditions of their parent fn + Some( + ty::ImplTraitInTraitData::Impl { fn_def_id } + | ty::ImplTraitInTraitData::Trait { fn_def_id, .. }, + ) => return tcx.const_conditions(fn_def_id), + None => {} + } + let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id) { Node::Item(item) => match item.kind { @@ -1053,19 +1062,29 @@ pub(super) fn explicit_implied_const_bounds<'tcx>( bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}"); } - let bounds = match tcx.hir_node_by_def_id(def_id) { - Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => { - implied_predicates_with_filter( - tcx, - def_id.to_def_id(), - PredicateFilter::SelfConstIfConst, - ) - } - Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) - | Node::OpaqueTy(_) => { + let bounds = match tcx.opt_rpitit_info(def_id.to_def_id()) { + // RPITIT's bounds are the same as opaque type bounds, but with + // a projection self type. + Some(ty::ImplTraitInTraitData::Trait { .. }) => { explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) } - _ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"), + Some(ty::ImplTraitInTraitData::Impl { .. }) => { + span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds") + } + None => match tcx.hir_node_by_def_id(def_id) { + Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => { + implied_predicates_with_filter( + tcx, + def_id.to_def_id(), + PredicateFilter::SelfConstIfConst, + ) + } + Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) + | Node::OpaqueTy(_) => { + explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) + } + _ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"), + }, }; bounds.map_bound(|bounds| { diff --git a/tests/ui/traits/const-traits/const-cond-for-rpitit.rs b/tests/ui/traits/const-traits/const-cond-for-rpitit.rs new file mode 100644 index 0000000000000..50bf93f9a0328 --- /dev/null +++ b/tests/ui/traits/const-traits/const-cond-for-rpitit.rs @@ -0,0 +1,22 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl)] +#![allow(refining_impl_trait)] + +#[const_trait] +pub trait Foo { + fn method(self) -> impl ~const Bar; +} + +#[const_trait] +pub trait Bar {} + +struct A(T); +impl const Foo for A where A: ~const Bar { + fn method(self) -> impl ~const Bar { + self + } +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs index 61b8c9a5bff83..d7fe43ef37ced 100644 --- a/tests/ui/traits/const-traits/const-impl-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-trait.rs @@ -1,15 +1,10 @@ //@ compile-flags: -Znext-solver //@ known-bug: #110395 -//@ failure-status: 101 -//@ dont-check-compiler-stderr -// Broken until we have `&T: const Deref` impl in stdlib + +// Broken until we have `const PartialEq` impl in stdlib #![allow(incomplete_features)] -#![feature( - const_trait_impl, - effects, - const_cmp, -)] +#![feature(const_trait_impl, const_cmp, const_destruct)] use std::marker::Destruct; @@ -17,9 +12,9 @@ const fn cmp(a: &impl ~const PartialEq) -> bool { a == a } -const fn wrap(x: impl ~const PartialEq + ~const Destruct) - -> impl ~const PartialEq + ~const Destruct -{ +const fn wrap( + x: impl ~const PartialEq + ~const Destruct, +) -> impl ~const PartialEq + ~const Destruct { x } @@ -48,11 +43,15 @@ trait T {} struct S; impl const T for S {} -const fn rpit() -> impl ~const T { S } +const fn rpit() -> impl ~const T { + S +} const fn apit(_: impl ~const T + ~const Destruct) {} -const fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } +const fn rpit_assoc_bound() -> impl IntoIterator { + Some(S) +} const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr new file mode 100644 index 0000000000000..cf1797e72d78a --- /dev/null +++ b/tests/ui/traits/const-traits/const-impl-trait.stderr @@ -0,0 +1,152 @@ +error[E0635]: unknown feature `const_cmp` + --> $DIR/const-impl-trait.rs:7:30 + | +LL | #![feature(const_trait_impl, const_cmp, const_destruct)] + | ^^^^^^^^^ + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:11:23 + | +LL | const fn cmp(a: &impl ~const PartialEq) -> bool { + | ^^^^^^ + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:11:23 + | +LL | const fn cmp(a: &impl ~const PartialEq) -> bool { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:16:13 + | +LL | x: impl ~const PartialEq + ~const Destruct, + | ^^^^^^ + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:11 + | +LL | ) -> impl ~const PartialEq + ~const Destruct { + | ^^^^^^ + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:11 + | +LL | ) -> impl ~const PartialEq + ~const Destruct { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:11 + | +LL | ) -> impl ~const PartialEq + ~const Destruct { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:16:13 + | +LL | x: impl ~const PartialEq + ~const Destruct, + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:23:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^ + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:27:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + | ^^^^^^ + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:27:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:23:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:23:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:27:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:23:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:23:22 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0015]: cannot call non-const operator in constants + --> $DIR/const-impl-trait.rs:35:13 + | +LL | assert!(wrap(123) == wrap(123)); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const operator in constants + --> $DIR/const-impl-trait.rs:36:13 + | +LL | assert!(wrap(123) != wrap(456)); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const operator in constants + --> $DIR/const-impl-trait.rs:38:13 + | +LL | assert!(x == x); + | ^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/const-impl-trait.rs:12:5 + | +LL | a == a + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 20 previous errors + +Some errors have detailed explanations: E0015, E0635. +For more information about an error, try `rustc --explain E0015`.