Skip to content

Commit 0ae3c5c

Browse files
BoxyUwUJulianKnodt
authored andcommitted
handle assoc consts in fulfill ConstEquate
1 parent d75cd5c commit 0ae3c5c

File tree

8 files changed

+88
-174
lines changed

8 files changed

+88
-174
lines changed

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -457,41 +457,45 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
457457
tcx.features().generic_const_exprs,
458458
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
459459
);
460-
debug!(?c1, ?c2, "equating consts");
461460
// FIXME: we probably should only try to unify abstract constants
462461
// if the constants depend on generic parameters.
463462
//
464463
// Let's just see where this breaks :shrug:
465-
match (c1.kind(), c2.kind()) {
466-
(ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) => {
467-
// FIXME: remove
468-
use rustc_hir::def::DefKind;
469-
if tcx.def_kind(a.def.did) == DefKind::AssocConst
470-
|| tcx.def_kind(b.def.did) == DefKind::AssocConst
464+
{
465+
let c1 =
466+
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1) { a } else { c1 };
467+
let c2 =
468+
if let Ok(Some(b)) = tcx.expand_abstract_consts(c2) { b } else { c2 };
469+
debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
470+
471+
use rustc_hir::def::DefKind;
472+
use ty::ConstKind::Unevaluated;
473+
match (c1.kind(), c2.kind()) {
474+
(Unevaluated(a), Unevaluated(b))
475+
if a.def.did == b.def.did
476+
&& tcx.def_kind(a.def.did) == DefKind::AssocConst =>
471477
{
472-
// Two different constants using generic parameters ~> error.
473-
let expected_found = ExpectedFound::new(true, c1, c2);
474-
return ProcessResult::Error(
475-
FulfillmentErrorCode::CodeConstEquateError(
476-
expected_found,
477-
TypeError::ConstMismatch(expected_found),
478-
),
479-
);
480-
}
481-
482-
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1)
483-
&& let Ok(Some(b)) = tcx.expand_abstract_consts(c2)
484-
&& a.ty() == b.ty()
485-
&& let Ok(new_obligations) = infcx
478+
if let Ok(new_obligations) = infcx
486479
.at(&obligation.cause, obligation.param_env)
487-
.eq(a, b)
480+
.trace(c1, c2)
481+
.eq(a.substs, b.substs)
488482
{
489483
return ProcessResult::Changed(mk_pending(
490484
new_obligations.into_obligations(),
491485
));
492486
}
487+
}
488+
(_, Unevaluated(_)) | (Unevaluated(_), _) => (),
489+
(_, _) => {
490+
if let Ok(new_obligations) =
491+
infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
492+
{
493+
return ProcessResult::Changed(mk_pending(
494+
new_obligations.into_obligations(),
495+
));
496+
}
497+
}
493498
}
494-
_ => {}
495499
}
496500

497501
let stalled_on = &mut pending_obligation.stalled_on;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// check-pass
2+
#![feature(generic_const_exprs)]
3+
#![allow(incomplete_features)]
4+
5+
trait Trait {
6+
const ASSOC: usize;
7+
}
8+
impl<T> Trait for T {
9+
const ASSOC: usize = std::mem::size_of::<T>();
10+
}
11+
12+
struct Foo<T: Trait>([u8; T::ASSOC])
13+
where
14+
[(); T::ASSOC]:;
15+
16+
fn bar<T: Trait>()
17+
where
18+
[(); T::ASSOC]:,
19+
{
20+
let _: Foo<T> = Foo::<_>(make());
21+
}
22+
23+
fn make() -> ! {
24+
todo!()
25+
}
26+
27+
fn main() {}

src/test/ui/const-generics/invariant.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ fn covariant(
2525
v: &'static Foo<for<'a> fn(&'a ())>
2626
) -> &'static Foo<fn(&'static ())> {
2727
v
28+
//~^ ERROR mismatched types
2829
}
2930

3031
fn main() {
31-
let y = covariant(&Foo([], PhantomData)); //~ ERROR mismatched types
32+
let y = covariant(&Foo([], PhantomData));
3233
println!("{:?}", y.0);
3334
}

src/test/ui/const-generics/invariant.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ LL | impl SadBee for fn(&'static ()) {
1313
= note: `#[warn(coherence_leak_check)]` on by default
1414

1515
error[E0308]: mismatched types
16-
--> $DIR/invariant.rs:31:28
16+
--> $DIR/invariant.rs:27:5
1717
|
18-
LL | let y = covariant(&Foo([], PhantomData));
19-
| ^^ expected `<_ as SadBee>::ASSOC`, found `<for<'a> fn(&'a ()) as SadBee>::ASSOC`
18+
LL | v
19+
| ^ one type is more general than the other
2020
|
21-
= note: expected constant `<_ as SadBee>::ASSOC`
22-
found constant `<for<'a> fn(&'a ()) as SadBee>::ASSOC`
21+
= note: expected reference `&Foo<fn(&())>`
22+
found reference `&Foo<for<'a> fn(&'a ())>`
2323

2424
error: aborting due to previous error; 1 warning emitted
2525

src/test/ui/const-generics/issues/issue-83249.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ fn foo<T: Foo>(_: [u8; T::N]) -> T {
1515

1616
pub fn bar() {
1717
let _: u8 = foo([0; 1]);
18-
//~^ ERROR mismatched types
19-
18+
2019
let _ = foo([0; 1]);
20+
//~^ ERROR type annotations needed
2121
}
2222

2323
fn main() {}
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/issue-83249.rs:17:21
1+
error[E0282]: type annotations needed
2+
--> $DIR/issue-83249.rs:19:9
33
|
4-
LL | let _: u8 = foo([0; 1]);
5-
| ^^^^^^ expected `<_ as Foo>::N`, found `<u8 as Foo>::N`
4+
LL | let _ = foo([0; 1]);
5+
| ^
66
|
7-
= note: expected constant `<_ as Foo>::N`
8-
found constant `<u8 as Foo>::N`
7+
help: consider giving this pattern a type
8+
|
9+
LL | let _: _ = foo([0; 1]);
10+
| +++
911

1012
error: aborting due to previous error
1113

12-
For more information about this error, try `rustc --explain E0308`.
14+
For more information about this error, try `rustc --explain E0282`.

src/test/ui/const-generics/issues/issue-83765.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
trait TensorDimension {
55
const DIM: usize;
6+
//~^ ERROR cycle detected when resolving instance
67
// FIXME Given the current state of the compiler its expected that we cycle here,
78
// but the cycle is still wrong.
89
const ISSCALAR: bool = Self::DIM == 0;
@@ -47,25 +48,19 @@ impl<'a, T: Broadcastable, const DIM: usize> TensorDimension for LazyUpdim<'a, T
4748

4849
impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> {
4950
fn size(&self) -> [usize; DIM] {
50-
//~^ ERROR method not compatible
5151
self.size
5252
}
5353
}
5454

5555
impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> {
5656
type Element = T::Element;
5757
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
58-
//~^ ERROR method not compatible
5958
assert!(DIM >= T::DIM);
6059
if !self.inbounds(index) {
61-
//~^ ERROR mismatched types
62-
//~^^ ERROR unconstrained generic constant
6360
return None;
6461
}
6562
let size = self.size();
66-
//~^ ERROR unconstrained generic constant
6763
let newindex: [usize; T::DIM] = Default::default();
68-
//~^ ERROR the trait bound
6964
self.reference.bget(newindex)
7065
}
7166
}
@@ -84,10 +79,7 @@ impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSi
8479
for BMap<'a, R, T, F, DIM>
8580
{
8681
fn size(&self) -> [usize; DIM] {
87-
//~^ ERROR method not compatible
8882
self.reference.size()
89-
//~^ ERROR unconstrained
90-
//~| ERROR mismatched types
9183
}
9284
}
9385

@@ -96,10 +88,7 @@ impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> Broadcas
9688
{
9789
type Element = R;
9890
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
99-
//~^ ERROR method not compatible
10091
self.reference.bget(index).map(&self.closure)
101-
//~^ ERROR unconstrained generic constant
102-
//~| ERROR mismatched types
10392
}
10493
}
10594

Lines changed: 15 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,21 @@
1-
error[E0308]: method not compatible with trait
2-
--> $DIR/issue-83765.rs:49:5
1+
error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`
2+
--> $DIR/issue-83765.rs:5:5
33
|
4-
LL | fn size(&self) -> [usize; DIM] {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
4+
LL | const DIM: usize;
5+
| ^^^^^^^^^^^^^^^^
66
|
7-
= note: expected constant `Self::DIM`
8-
found constant `DIM`
9-
10-
error[E0308]: method not compatible with trait
11-
--> $DIR/issue-83765.rs:57:5
12-
|
13-
LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
15-
|
16-
= note: expected constant `Self::DIM`
17-
found constant `DIM`
18-
19-
error[E0308]: method not compatible with trait
20-
--> $DIR/issue-83765.rs:86:5
21-
|
22-
LL | fn size(&self) -> [usize; DIM] {
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
24-
|
25-
= note: expected constant `Self::DIM`
26-
found constant `DIM`
27-
28-
error[E0308]: method not compatible with trait
29-
--> $DIR/issue-83765.rs:98:5
30-
|
31-
LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
32-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
33-
|
34-
= note: expected constant `Self::DIM`
35-
found constant `DIM`
36-
37-
error: unconstrained generic constant
38-
--> $DIR/issue-83765.rs:60:18
39-
|
40-
LL | if !self.inbounds(index) {
41-
| ^^^^^^^^
42-
|
43-
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
44-
note: required by a bound in `TensorSize::inbounds`
45-
--> $DIR/issue-83765.rs:16:39
46-
|
47-
LL | fn inbounds(&self, index: [usize; Self::DIM]) -> bool {
48-
| ^^^^^^^^^ required by this bound in `TensorSize::inbounds`
49-
50-
error[E0308]: mismatched types
51-
--> $DIR/issue-83765.rs:60:27
52-
|
53-
LL | if !self.inbounds(index) {
54-
| ^^^^^ expected `Self::DIM`, found `DIM`
55-
|
56-
= note: expected constant `Self::DIM`
57-
found constant `DIM`
58-
59-
error: unconstrained generic constant
60-
--> $DIR/issue-83765.rs:65:25
61-
|
62-
LL | let size = self.size();
63-
| ^^^^
64-
|
65-
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
66-
note: required by a bound in `TensorSize::size`
67-
--> $DIR/issue-83765.rs:15:31
68-
|
69-
LL | fn size(&self) -> [usize; Self::DIM];
70-
| ^^^^^^^^^ required by this bound in `TensorSize::size`
71-
72-
error[E0277]: the trait bound `[usize; _]: Default` is not satisfied
73-
--> $DIR/issue-83765.rs:67:41
74-
|
75-
LL | let newindex: [usize; T::DIM] = Default::default();
76-
| ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[usize; _]`
77-
|
78-
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
79-
|
80-
LL | impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> where [usize; _]: Default {
81-
| +++++++++++++++++++++++++
82-
83-
error: unconstrained generic constant
84-
--> $DIR/issue-83765.rs:88:24
85-
|
86-
LL | self.reference.size()
87-
| ^^^^
88-
|
89-
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
90-
note: required by a bound in `TensorSize::size`
91-
--> $DIR/issue-83765.rs:15:31
92-
|
93-
LL | fn size(&self) -> [usize; Self::DIM];
94-
| ^^^^^^^^^ required by this bound in `TensorSize::size`
95-
96-
error[E0308]: mismatched types
97-
--> $DIR/issue-83765.rs:88:9
98-
|
99-
LL | self.reference.size()
100-
| ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
101-
|
102-
= note: expected constant `DIM`
103-
found constant `Self::DIM`
104-
105-
error: unconstrained generic constant
106-
--> $DIR/issue-83765.rs:100:24
107-
|
108-
LL | self.reference.bget(index).map(&self.closure)
109-
| ^^^^
110-
|
111-
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
112-
note: required by a bound in `Broadcastable::bget`
113-
--> $DIR/issue-83765.rs:23:35
114-
|
115-
LL | fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>;
116-
| ^^^^^^^^^ required by this bound in `Broadcastable::bget`
117-
118-
error[E0308]: mismatched types
119-
--> $DIR/issue-83765.rs:100:29
7+
note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
8+
--> $DIR/issue-83765.rs:4:1
1209
|
121-
LL | self.reference.bget(index).map(&self.closure)
122-
| ^^^^^ expected `Self::DIM`, found `DIM`
10+
LL | trait TensorDimension {
11+
| ^^^^^^^^^^^^^^^^^^^^^
12+
= note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle
13+
note: cycle used when computing candidate for `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>`
14+
--> $DIR/issue-83765.rs:4:1
12315
|
124-
= note: expected constant `Self::DIM`
125-
found constant `DIM`
16+
LL | trait TensorDimension {
17+
| ^^^^^^^^^^^^^^^^^^^^^
12618

127-
error: aborting due to 12 previous errors
19+
error: aborting due to previous error
12820

129-
Some errors have detailed explanations: E0277, E0308.
130-
For more information about an error, try `rustc --explain E0277`.
21+
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)