Skip to content

Commit 50f6238

Browse files
Fix const conditions for RPITITs
1 parent 0e98766 commit 50f6238

File tree

5 files changed

+219
-28
lines changed

5 files changed

+219
-28
lines changed

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,9 @@ pub(super) fn explicit_item_bounds_with_filter(
371371
associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter);
372372
return ty::EarlyBinder::bind(bounds);
373373
}
374-
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
375-
tcx.def_span(def_id),
376-
"item bounds for RPITIT in impl to be fed on def-id creation"
377-
),
374+
Some(ty::ImplTraitInTraitData::Impl { .. }) => {
375+
span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds")
376+
}
378377
None => {}
379378
}
380379

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+30-11
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,15 @@ pub(super) fn const_conditions<'tcx>(
950950
bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
951951
}
952952

953+
match tcx.opt_rpitit_info(def_id.to_def_id()) {
954+
// RPITITs inherit const conditions of their parent fn
955+
Some(
956+
ty::ImplTraitInTraitData::Impl { fn_def_id }
957+
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
958+
) => return tcx.const_conditions(fn_def_id),
959+
None => {}
960+
}
961+
953962
let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id)
954963
{
955964
Node::Item(item) => match item.kind {
@@ -1053,19 +1062,29 @@ pub(super) fn explicit_implied_const_bounds<'tcx>(
10531062
bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
10541063
}
10551064

1056-
let bounds = match tcx.hir_node_by_def_id(def_id) {
1057-
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
1058-
implied_predicates_with_filter(
1059-
tcx,
1060-
def_id.to_def_id(),
1061-
PredicateFilter::SelfConstIfConst,
1062-
)
1063-
}
1064-
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
1065-
| Node::OpaqueTy(_) => {
1065+
let bounds = match tcx.opt_rpitit_info(def_id.to_def_id()) {
1066+
// RPITIT's bounds are the same as opaque type bounds, but with
1067+
// a projection self type.
1068+
Some(ty::ImplTraitInTraitData::Trait { .. }) => {
10661069
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
10671070
}
1068-
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
1071+
Some(ty::ImplTraitInTraitData::Impl { .. }) => {
1072+
span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds")
1073+
}
1074+
None => match tcx.hir_node_by_def_id(def_id) {
1075+
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
1076+
implied_predicates_with_filter(
1077+
tcx,
1078+
def_id.to_def_id(),
1079+
PredicateFilter::SelfConstIfConst,
1080+
)
1081+
}
1082+
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
1083+
| Node::OpaqueTy(_) => {
1084+
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
1085+
}
1086+
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
1087+
},
10691088
};
10701089

10711090
bounds.map_bound(|bounds| {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
#![feature(const_trait_impl)]
5+
#![allow(refining_impl_trait)]
6+
7+
#[const_trait]
8+
pub trait Foo {
9+
fn method(self) -> impl ~const Bar;
10+
}
11+
12+
#[const_trait]
13+
pub trait Bar {}
14+
15+
struct A<T>(T);
16+
impl<T> const Foo for A<T> where A<T>: ~const Bar {
17+
fn method(self) -> impl ~const Bar {
18+
self
19+
}
20+
}
21+
22+
fn main() {}

tests/ui/traits/const-traits/const-impl-trait.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
//@ compile-flags: -Znext-solver
22
//@ known-bug: #110395
3-
//@ failure-status: 101
4-
//@ dont-check-compiler-stderr
5-
// Broken until we have `&T: const Deref` impl in stdlib
3+
4+
// Broken until we have `const PartialEq` impl in stdlib
65

76
#![allow(incomplete_features)]
8-
#![feature(
9-
const_trait_impl,
10-
effects,
11-
const_cmp,
12-
)]
7+
#![feature(const_trait_impl, const_cmp, const_destruct)]
138

149
use std::marker::Destruct;
1510

1611
const fn cmp(a: &impl ~const PartialEq) -> bool {
1712
a == a
1813
}
1914

20-
const fn wrap(x: impl ~const PartialEq + ~const Destruct)
21-
-> impl ~const PartialEq + ~const Destruct
22-
{
15+
const fn wrap(
16+
x: impl ~const PartialEq + ~const Destruct,
17+
) -> impl ~const PartialEq + ~const Destruct {
2318
x
2419
}
2520

@@ -48,11 +43,15 @@ trait T {}
4843
struct S;
4944
impl const T for S {}
5045

51-
const fn rpit() -> impl ~const T { S }
46+
const fn rpit() -> impl ~const T {
47+
S
48+
}
5249

5350
const fn apit(_: impl ~const T + ~const Destruct) {}
5451

55-
const fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
52+
const fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> {
53+
Some(S)
54+
}
5655

5756
const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
5857

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
error[E0635]: unknown feature `const_cmp`
2+
--> $DIR/const-impl-trait.rs:7:30
3+
|
4+
LL | #![feature(const_trait_impl, const_cmp, const_destruct)]
5+
| ^^^^^^^^^
6+
7+
error: `~const` can only be applied to `#[const_trait]` traits
8+
--> $DIR/const-impl-trait.rs:11:23
9+
|
10+
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
11+
| ^^^^^^
12+
13+
error: `~const` can only be applied to `#[const_trait]` traits
14+
--> $DIR/const-impl-trait.rs:11:23
15+
|
16+
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
17+
| ^^^^^^
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
21+
error: `~const` can only be applied to `#[const_trait]` traits
22+
--> $DIR/const-impl-trait.rs:16:13
23+
|
24+
LL | x: impl ~const PartialEq + ~const Destruct,
25+
| ^^^^^^
26+
27+
error: `~const` can only be applied to `#[const_trait]` traits
28+
--> $DIR/const-impl-trait.rs:17:11
29+
|
30+
LL | ) -> impl ~const PartialEq + ~const Destruct {
31+
| ^^^^^^
32+
33+
error: `~const` can only be applied to `#[const_trait]` traits
34+
--> $DIR/const-impl-trait.rs:17:11
35+
|
36+
LL | ) -> impl ~const PartialEq + ~const Destruct {
37+
| ^^^^^^
38+
|
39+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
40+
41+
error: `~const` can only be applied to `#[const_trait]` traits
42+
--> $DIR/const-impl-trait.rs:17:11
43+
|
44+
LL | ) -> impl ~const PartialEq + ~const Destruct {
45+
| ^^^^^^
46+
|
47+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
48+
49+
error: `~const` can only be applied to `#[const_trait]` traits
50+
--> $DIR/const-impl-trait.rs:16:13
51+
|
52+
LL | x: impl ~const PartialEq + ~const Destruct,
53+
| ^^^^^^
54+
|
55+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
56+
57+
error: `~const` can only be applied to `#[const_trait]` traits
58+
--> $DIR/const-impl-trait.rs:23:22
59+
|
60+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
61+
| ^^^^^^
62+
63+
error: `~const` can only be applied to `#[const_trait]` traits
64+
--> $DIR/const-impl-trait.rs:27:22
65+
|
66+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
67+
| ^^^^^^
68+
69+
error: `~const` can only be applied to `#[const_trait]` traits
70+
--> $DIR/const-impl-trait.rs:27:22
71+
|
72+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
73+
| ^^^^^^
74+
|
75+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
76+
77+
error: `~const` can only be applied to `#[const_trait]` traits
78+
--> $DIR/const-impl-trait.rs:23:22
79+
|
80+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
81+
| ^^^^^^
82+
|
83+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
84+
85+
error: `~const` can only be applied to `#[const_trait]` traits
86+
--> $DIR/const-impl-trait.rs:23:22
87+
|
88+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
89+
| ^^^^^^
90+
|
91+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
92+
93+
error: `~const` can only be applied to `#[const_trait]` traits
94+
--> $DIR/const-impl-trait.rs:27:22
95+
|
96+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
97+
| ^^^^^^
98+
|
99+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
100+
101+
error: `~const` can only be applied to `#[const_trait]` traits
102+
--> $DIR/const-impl-trait.rs:23:22
103+
|
104+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
105+
| ^^^^^^
106+
|
107+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
108+
109+
error: `~const` can only be applied to `#[const_trait]` traits
110+
--> $DIR/const-impl-trait.rs:23:22
111+
|
112+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
113+
| ^^^^^^
114+
|
115+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
116+
117+
error[E0015]: cannot call non-const operator in constants
118+
--> $DIR/const-impl-trait.rs:35:13
119+
|
120+
LL | assert!(wrap(123) == wrap(123));
121+
| ^^^^^^^^^^^^^^^^^^^^^^
122+
|
123+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
124+
125+
error[E0015]: cannot call non-const operator in constants
126+
--> $DIR/const-impl-trait.rs:36:13
127+
|
128+
LL | assert!(wrap(123) != wrap(456));
129+
| ^^^^^^^^^^^^^^^^^^^^^^
130+
|
131+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
132+
133+
error[E0015]: cannot call non-const operator in constants
134+
--> $DIR/const-impl-trait.rs:38:13
135+
|
136+
LL | assert!(x == x);
137+
| ^^^^^^
138+
|
139+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
140+
141+
error[E0015]: cannot call non-const operator in constant functions
142+
--> $DIR/const-impl-trait.rs:12:5
143+
|
144+
LL | a == a
145+
| ^^^^^^
146+
|
147+
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
148+
149+
error: aborting due to 20 previous errors
150+
151+
Some errors have detailed explanations: E0015, E0635.
152+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)