Fix const conditions for RPITITs
This commit is contained in:
parent
52890e8215
commit
4977640c79
5 changed files with 254 additions and 28 deletions
|
@ -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 => {}
|
||||
}
|
||||
|
||||
|
|
|
@ -957,6 +957,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 {
|
||||
|
@ -1060,19 +1069,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| {
|
||||
|
|
22
tests/ui/traits/const-traits/const-cond-for-rpitit.rs
Normal file
22
tests/ui/traits/const-traits/const-cond-for-rpitit.rs
Normal file
|
@ -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>(T);
|
||||
impl<T> const Foo for A<T> where A<T>: ~const Bar {
|
||||
fn method(self) -> impl ~const Bar {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -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<Item: ~const T> { Some(S) }
|
||||
const fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> {
|
||||
Some(S)
|
||||
}
|
||||
|
||||
const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
|
||||
|
||||
|
|
187
tests/ui/traits/const-traits/const-impl-trait.stderr
Normal file
187
tests/ui/traits/const-traits/const-impl-trait.stderr
Normal file
|
@ -0,0 +1,187 @@
|
|||
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 {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
|
||||
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 {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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,
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:17:11
|
||||
|
|
||||
LL | ) -> impl ~const PartialEq + ~const Destruct {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:17:11
|
||||
|
|
||||
LL | ) -> impl ~const PartialEq + ~const Destruct {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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 {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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,
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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;
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
|
||||
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 {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
|
||||
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 {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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;
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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;
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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 {
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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;
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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;
|
||||
| ^^^^^^ can't be applied to `PartialEq`
|
||||
|
|
||||
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
|
||||
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
||||
= 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`.
|
Loading…
Add table
Reference in a new issue