Skip to content

Commit 81fccef

Browse files
authored
Rollup merge of #133926 - compiler-errors:const-conditions, r=lcnr
Fix const conditions for RPITITs Fixes #133918 r? lcnr
2 parents 2d08e94 + 4977640 commit 81fccef

File tree

5 files changed

+254
-28
lines changed

5 files changed

+254
-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
@@ -956,6 +956,15 @@ pub(super) fn const_conditions<'tcx>(
956956
bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
957957
}
958958

959+
match tcx.opt_rpitit_info(def_id.to_def_id()) {
960+
// RPITITs inherit const conditions of their parent fn
961+
Some(
962+
ty::ImplTraitInTraitData::Impl { fn_def_id }
963+
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
964+
) => return tcx.const_conditions(fn_def_id),
965+
None => {}
966+
}
967+
959968
let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id)
960969
{
961970
Node::Item(item) => match item.kind {
@@ -1059,19 +1068,29 @@ pub(super) fn explicit_implied_const_bounds<'tcx>(
10591068
bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
10601069
}
10611070

1062-
let bounds = match tcx.hir_node_by_def_id(def_id) {
1063-
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
1064-
implied_predicates_with_filter(
1065-
tcx,
1066-
def_id.to_def_id(),
1067-
PredicateFilter::SelfConstIfConst,
1068-
)
1069-
}
1070-
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
1071-
| Node::OpaqueTy(_) => {
1071+
let bounds = match tcx.opt_rpitit_info(def_id.to_def_id()) {
1072+
// RPITIT's bounds are the same as opaque type bounds, but with
1073+
// a projection self type.
1074+
Some(ty::ImplTraitInTraitData::Trait { .. }) => {
10721075
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
10731076
}
1074-
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
1077+
Some(ty::ImplTraitInTraitData::Impl { .. }) => {
1078+
span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds")
1079+
}
1080+
None => match tcx.hir_node_by_def_id(def_id) {
1081+
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
1082+
implied_predicates_with_filter(
1083+
tcx,
1084+
def_id.to_def_id(),
1085+
PredicateFilter::SelfConstIfConst,
1086+
)
1087+
}
1088+
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
1089+
| Node::OpaqueTy(_) => {
1090+
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
1091+
}
1092+
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
1093+
},
10751094
};
10761095

10771096
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,187 @@
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+
| ^^^^^^ can't be applied to `PartialEq`
12+
|
13+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
14+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
15+
16+
error: `~const` can only be applied to `#[const_trait]` traits
17+
--> $DIR/const-impl-trait.rs:11:23
18+
|
19+
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
20+
| ^^^^^^ can't be applied to `PartialEq`
21+
|
22+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
23+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
24+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
25+
26+
error: `~const` can only be applied to `#[const_trait]` traits
27+
--> $DIR/const-impl-trait.rs:16:13
28+
|
29+
LL | x: impl ~const PartialEq + ~const Destruct,
30+
| ^^^^^^ can't be applied to `PartialEq`
31+
|
32+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
33+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
34+
35+
error: `~const` can only be applied to `#[const_trait]` traits
36+
--> $DIR/const-impl-trait.rs:17:11
37+
|
38+
LL | ) -> impl ~const PartialEq + ~const Destruct {
39+
| ^^^^^^ can't be applied to `PartialEq`
40+
|
41+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
42+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
43+
44+
error: `~const` can only be applied to `#[const_trait]` traits
45+
--> $DIR/const-impl-trait.rs:17:11
46+
|
47+
LL | ) -> impl ~const PartialEq + ~const Destruct {
48+
| ^^^^^^ can't be applied to `PartialEq`
49+
|
50+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
51+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
52+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
53+
54+
error: `~const` can only be applied to `#[const_trait]` traits
55+
--> $DIR/const-impl-trait.rs:17:11
56+
|
57+
LL | ) -> impl ~const PartialEq + ~const Destruct {
58+
| ^^^^^^ can't be applied to `PartialEq`
59+
|
60+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
61+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
62+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
63+
64+
error: `~const` can only be applied to `#[const_trait]` traits
65+
--> $DIR/const-impl-trait.rs:16:13
66+
|
67+
LL | x: impl ~const PartialEq + ~const Destruct,
68+
| ^^^^^^ can't be applied to `PartialEq`
69+
|
70+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
71+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
72+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
73+
74+
error: `~const` can only be applied to `#[const_trait]` traits
75+
--> $DIR/const-impl-trait.rs:23:22
76+
|
77+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
78+
| ^^^^^^ can't be applied to `PartialEq`
79+
|
80+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
81+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
82+
83+
error: `~const` can only be applied to `#[const_trait]` traits
84+
--> $DIR/const-impl-trait.rs:27:22
85+
|
86+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
87+
| ^^^^^^ can't be applied to `PartialEq`
88+
|
89+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
90+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
91+
92+
error: `~const` can only be applied to `#[const_trait]` traits
93+
--> $DIR/const-impl-trait.rs:27:22
94+
|
95+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
96+
| ^^^^^^ can't be applied to `PartialEq`
97+
|
98+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
99+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
100+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
101+
102+
error: `~const` can only be applied to `#[const_trait]` traits
103+
--> $DIR/const-impl-trait.rs:23:22
104+
|
105+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
106+
| ^^^^^^ can't be applied to `PartialEq`
107+
|
108+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
109+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
110+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
111+
112+
error: `~const` can only be applied to `#[const_trait]` traits
113+
--> $DIR/const-impl-trait.rs:23:22
114+
|
115+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
116+
| ^^^^^^ can't be applied to `PartialEq`
117+
|
118+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
119+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
120+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
121+
122+
error: `~const` can only be applied to `#[const_trait]` traits
123+
--> $DIR/const-impl-trait.rs:27:22
124+
|
125+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
126+
| ^^^^^^ can't be applied to `PartialEq`
127+
|
128+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
129+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
130+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
131+
132+
error: `~const` can only be applied to `#[const_trait]` traits
133+
--> $DIR/const-impl-trait.rs:23:22
134+
|
135+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
136+
| ^^^^^^ can't be applied to `PartialEq`
137+
|
138+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
139+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
140+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
141+
142+
error: `~const` can only be applied to `#[const_trait]` traits
143+
--> $DIR/const-impl-trait.rs:23:22
144+
|
145+
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
146+
| ^^^^^^ can't be applied to `PartialEq`
147+
|
148+
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
149+
--> $SRC_DIR/core/src/cmp.rs:LL:COL
150+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
151+
152+
error[E0015]: cannot call non-const operator in constants
153+
--> $DIR/const-impl-trait.rs:35:13
154+
|
155+
LL | assert!(wrap(123) == wrap(123));
156+
| ^^^^^^^^^^^^^^^^^^^^^^
157+
|
158+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
159+
160+
error[E0015]: cannot call non-const operator in constants
161+
--> $DIR/const-impl-trait.rs:36:13
162+
|
163+
LL | assert!(wrap(123) != wrap(456));
164+
| ^^^^^^^^^^^^^^^^^^^^^^
165+
|
166+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
167+
168+
error[E0015]: cannot call non-const operator in constants
169+
--> $DIR/const-impl-trait.rs:38:13
170+
|
171+
LL | assert!(x == x);
172+
| ^^^^^^
173+
|
174+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
175+
176+
error[E0015]: cannot call non-const operator in constant functions
177+
--> $DIR/const-impl-trait.rs:12:5
178+
|
179+
LL | a == a
180+
| ^^^^^^
181+
|
182+
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
183+
184+
error: aborting due to 20 previous errors
185+
186+
Some errors have detailed explanations: E0015, E0635.
187+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)