handle assoc consts in fulfill ConstEquate
This commit is contained in:
parent
d75cd5c051
commit
0ae3c5c609
8 changed files with 90 additions and 176 deletions
|
@ -457,41 +457,45 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
tcx.features().generic_const_exprs,
|
tcx.features().generic_const_exprs,
|
||||||
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
|
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
|
||||||
);
|
);
|
||||||
debug!(?c1, ?c2, "equating consts");
|
|
||||||
// FIXME: we probably should only try to unify abstract constants
|
// FIXME: we probably should only try to unify abstract constants
|
||||||
// if the constants depend on generic parameters.
|
// if the constants depend on generic parameters.
|
||||||
//
|
//
|
||||||
// Let's just see where this breaks :shrug:
|
// Let's just see where this breaks :shrug:
|
||||||
match (c1.kind(), c2.kind()) {
|
{
|
||||||
(ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) => {
|
let c1 =
|
||||||
// FIXME: remove
|
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1) { a } else { c1 };
|
||||||
use rustc_hir::def::DefKind;
|
let c2 =
|
||||||
if tcx.def_kind(a.def.did) == DefKind::AssocConst
|
if let Ok(Some(b)) = tcx.expand_abstract_consts(c2) { b } else { c2 };
|
||||||
|| tcx.def_kind(b.def.did) == DefKind::AssocConst
|
debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
|
||||||
{
|
|
||||||
// Two different constants using generic parameters ~> error.
|
|
||||||
let expected_found = ExpectedFound::new(true, c1, c2);
|
|
||||||
return ProcessResult::Error(
|
|
||||||
FulfillmentErrorCode::CodeConstEquateError(
|
|
||||||
expected_found,
|
|
||||||
TypeError::ConstMismatch(expected_found),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1)
|
use rustc_hir::def::DefKind;
|
||||||
&& let Ok(Some(b)) = tcx.expand_abstract_consts(c2)
|
use ty::ConstKind::Unevaluated;
|
||||||
&& a.ty() == b.ty()
|
match (c1.kind(), c2.kind()) {
|
||||||
&& let Ok(new_obligations) = infcx
|
(Unevaluated(a), Unevaluated(b))
|
||||||
|
if a.def.did == b.def.did
|
||||||
|
&& tcx.def_kind(a.def.did) == DefKind::AssocConst =>
|
||||||
|
{
|
||||||
|
if let Ok(new_obligations) = infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.eq(a, b)
|
.trace(c1, c2)
|
||||||
|
.eq(a.substs, b.substs)
|
||||||
{
|
{
|
||||||
return ProcessResult::Changed(mk_pending(
|
return ProcessResult::Changed(mk_pending(
|
||||||
new_obligations.into_obligations(),
|
new_obligations.into_obligations(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
(_, Unevaluated(_)) | (Unevaluated(_), _) => (),
|
||||||
|
(_, _) => {
|
||||||
|
if let Ok(new_obligations) =
|
||||||
|
infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
|
||||||
|
{
|
||||||
|
return ProcessResult::Changed(mk_pending(
|
||||||
|
new_obligations.into_obligations(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let stalled_on = &mut pending_obligation.stalled_on;
|
let stalled_on = &mut pending_obligation.stalled_on;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
const ASSOC: usize;
|
||||||
|
}
|
||||||
|
impl<T> Trait for T {
|
||||||
|
const ASSOC: usize = std::mem::size_of::<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo<T: Trait>([u8; T::ASSOC])
|
||||||
|
where
|
||||||
|
[(); T::ASSOC]:;
|
||||||
|
|
||||||
|
fn bar<T: Trait>()
|
||||||
|
where
|
||||||
|
[(); T::ASSOC]:,
|
||||||
|
{
|
||||||
|
let _: Foo<T> = Foo::<_>(make());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make() -> ! {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -25,9 +25,10 @@ fn covariant(
|
||||||
v: &'static Foo<for<'a> fn(&'a ())>
|
v: &'static Foo<for<'a> fn(&'a ())>
|
||||||
) -> &'static Foo<fn(&'static ())> {
|
) -> &'static Foo<fn(&'static ())> {
|
||||||
v
|
v
|
||||||
|
//~^ ERROR mismatched types
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let y = covariant(&Foo([], PhantomData)); //~ ERROR mismatched types
|
let y = covariant(&Foo([], PhantomData));
|
||||||
println!("{:?}", y.0);
|
println!("{:?}", y.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ LL | impl SadBee for fn(&'static ()) {
|
||||||
= note: `#[warn(coherence_leak_check)]` on by default
|
= note: `#[warn(coherence_leak_check)]` on by default
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/invariant.rs:31:28
|
--> $DIR/invariant.rs:27:5
|
||||||
|
|
|
|
||||||
LL | let y = covariant(&Foo([], PhantomData));
|
LL | v
|
||||||
| ^^ expected `<_ as SadBee>::ASSOC`, found `<for<'a> fn(&'a ()) as SadBee>::ASSOC`
|
| ^ one type is more general than the other
|
||||||
|
|
|
|
||||||
= note: expected constant `<_ as SadBee>::ASSOC`
|
= note: expected reference `&Foo<fn(&())>`
|
||||||
found constant `<for<'a> fn(&'a ()) as SadBee>::ASSOC`
|
found reference `&Foo<for<'a> fn(&'a ())>`
|
||||||
|
|
||||||
error: aborting due to previous error; 1 warning emitted
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ fn foo<T: Foo>(_: [u8; T::N]) -> T {
|
||||||
|
|
||||||
pub fn bar() {
|
pub fn bar() {
|
||||||
let _: u8 = foo([0; 1]);
|
let _: u8 = foo([0; 1]);
|
||||||
//~^ ERROR mismatched types
|
|
||||||
|
|
||||||
let _ = foo([0; 1]);
|
let _ = foo([0; 1]);
|
||||||
|
//~^ ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
error[E0308]: mismatched types
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/issue-83249.rs:17:21
|
--> $DIR/issue-83249.rs:19:9
|
||||||
|
|
|
|
||||||
LL | let _: u8 = foo([0; 1]);
|
LL | let _ = foo([0; 1]);
|
||||||
| ^^^^^^ expected `<_ as Foo>::N`, found `<u8 as Foo>::N`
|
| ^
|
||||||
|
|
|
|
||||||
= note: expected constant `<_ as Foo>::N`
|
help: consider giving this pattern a type
|
||||||
found constant `<u8 as Foo>::N`
|
|
|
||||||
|
LL | let _: _ = foo([0; 1]);
|
||||||
|
| +++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0282`.
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
trait TensorDimension {
|
trait TensorDimension {
|
||||||
const DIM: usize;
|
const DIM: usize;
|
||||||
|
//~^ ERROR cycle detected when resolving instance
|
||||||
// FIXME Given the current state of the compiler its expected that we cycle here,
|
// FIXME Given the current state of the compiler its expected that we cycle here,
|
||||||
// but the cycle is still wrong.
|
// but the cycle is still wrong.
|
||||||
const ISSCALAR: bool = Self::DIM == 0;
|
const ISSCALAR: bool = Self::DIM == 0;
|
||||||
|
@ -47,7 +48,6 @@ impl<'a, T: Broadcastable, const DIM: usize> TensorDimension for LazyUpdim<'a, T
|
||||||
|
|
||||||
impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> {
|
impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> {
|
||||||
fn size(&self) -> [usize; DIM] {
|
fn size(&self) -> [usize; DIM] {
|
||||||
//~^ ERROR method not compatible
|
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,17 +55,12 @@ impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T
|
||||||
impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> {
|
impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> {
|
||||||
type Element = T::Element;
|
type Element = T::Element;
|
||||||
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
||||||
//~^ ERROR method not compatible
|
|
||||||
assert!(DIM >= T::DIM);
|
assert!(DIM >= T::DIM);
|
||||||
if !self.inbounds(index) {
|
if !self.inbounds(index) {
|
||||||
//~^ ERROR mismatched types
|
|
||||||
//~^^ ERROR unconstrained generic constant
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let size = self.size();
|
let size = self.size();
|
||||||
//~^ ERROR unconstrained generic constant
|
|
||||||
let newindex: [usize; T::DIM] = Default::default();
|
let newindex: [usize; T::DIM] = Default::default();
|
||||||
//~^ ERROR the trait bound
|
|
||||||
self.reference.bget(newindex)
|
self.reference.bget(newindex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,10 +79,7 @@ impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSi
|
||||||
for BMap<'a, R, T, F, DIM>
|
for BMap<'a, R, T, F, DIM>
|
||||||
{
|
{
|
||||||
fn size(&self) -> [usize; DIM] {
|
fn size(&self) -> [usize; DIM] {
|
||||||
//~^ ERROR method not compatible
|
|
||||||
self.reference.size()
|
self.reference.size()
|
||||||
//~^ ERROR unconstrained
|
|
||||||
//~| ERROR mismatched types
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,10 +88,7 @@ impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> Broadcas
|
||||||
{
|
{
|
||||||
type Element = R;
|
type Element = R;
|
||||||
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
||||||
//~^ ERROR method not compatible
|
|
||||||
self.reference.bget(index).map(&self.closure)
|
self.reference.bget(index).map(&self.closure)
|
||||||
//~^ ERROR unconstrained generic constant
|
|
||||||
//~| ERROR mismatched types
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,130 +1,21 @@
|
||||||
error[E0308]: method not compatible with trait
|
error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`
|
||||||
--> $DIR/issue-83765.rs:49:5
|
--> $DIR/issue-83765.rs:5:5
|
||||||
|
|
|
|
||||||
LL | fn size(&self) -> [usize; DIM] {
|
LL | const DIM: usize;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: expected constant `Self::DIM`
|
note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
|
||||||
found constant `DIM`
|
--> $DIR/issue-83765.rs:4:1
|
||||||
|
|
|
||||||
|
LL | trait TensorDimension {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle
|
||||||
|
note: cycle used when computing candidate for `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>`
|
||||||
|
--> $DIR/issue-83765.rs:4:1
|
||||||
|
|
|
||||||
|
LL | trait TensorDimension {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0308]: method not compatible with trait
|
error: aborting due to previous error
|
||||||
--> $DIR/issue-83765.rs:57:5
|
|
||||||
|
|
|
||||||
LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
|
|
||||||
|
|
|
||||||
= note: expected constant `Self::DIM`
|
|
||||||
found constant `DIM`
|
|
||||||
|
|
||||||
error[E0308]: method not compatible with trait
|
For more information about this error, try `rustc --explain E0391`.
|
||||||
--> $DIR/issue-83765.rs:86:5
|
|
||||||
|
|
|
||||||
LL | fn size(&self) -> [usize; DIM] {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
|
|
||||||
|
|
|
||||||
= note: expected constant `Self::DIM`
|
|
||||||
found constant `DIM`
|
|
||||||
|
|
||||||
error[E0308]: method not compatible with trait
|
|
||||||
--> $DIR/issue-83765.rs:98:5
|
|
||||||
|
|
|
||||||
LL | fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
|
|
||||||
|
|
|
||||||
= note: expected constant `Self::DIM`
|
|
||||||
found constant `DIM`
|
|
||||||
|
|
||||||
error: unconstrained generic constant
|
|
||||||
--> $DIR/issue-83765.rs:60:18
|
|
||||||
|
|
|
||||||
LL | if !self.inbounds(index) {
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
|
|
||||||
note: required by a bound in `TensorSize::inbounds`
|
|
||||||
--> $DIR/issue-83765.rs:16:39
|
|
||||||
|
|
|
||||||
LL | fn inbounds(&self, index: [usize; Self::DIM]) -> bool {
|
|
||||||
| ^^^^^^^^^ required by this bound in `TensorSize::inbounds`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/issue-83765.rs:60:27
|
|
||||||
|
|
|
||||||
LL | if !self.inbounds(index) {
|
|
||||||
| ^^^^^ expected `Self::DIM`, found `DIM`
|
|
||||||
|
|
|
||||||
= note: expected constant `Self::DIM`
|
|
||||||
found constant `DIM`
|
|
||||||
|
|
||||||
error: unconstrained generic constant
|
|
||||||
--> $DIR/issue-83765.rs:65:25
|
|
||||||
|
|
|
||||||
LL | let size = self.size();
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
|
|
||||||
note: required by a bound in `TensorSize::size`
|
|
||||||
--> $DIR/issue-83765.rs:15:31
|
|
||||||
|
|
|
||||||
LL | fn size(&self) -> [usize; Self::DIM];
|
|
||||||
| ^^^^^^^^^ required by this bound in `TensorSize::size`
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `[usize; _]: Default` is not satisfied
|
|
||||||
--> $DIR/issue-83765.rs:67:41
|
|
||||||
|
|
|
||||||
LL | let newindex: [usize; T::DIM] = Default::default();
|
|
||||||
| ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[usize; _]`
|
|
||||||
|
|
|
||||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
|
||||||
|
|
|
||||||
LL | impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> where [usize; _]: Default {
|
|
||||||
| +++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: unconstrained generic constant
|
|
||||||
--> $DIR/issue-83765.rs:88:24
|
|
||||||
|
|
|
||||||
LL | self.reference.size()
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
|
|
||||||
note: required by a bound in `TensorSize::size`
|
|
||||||
--> $DIR/issue-83765.rs:15:31
|
|
||||||
|
|
|
||||||
LL | fn size(&self) -> [usize; Self::DIM];
|
|
||||||
| ^^^^^^^^^ required by this bound in `TensorSize::size`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/issue-83765.rs:88:9
|
|
||||||
|
|
|
||||||
LL | self.reference.size()
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
|
|
||||||
|
|
|
||||||
= note: expected constant `DIM`
|
|
||||||
found constant `Self::DIM`
|
|
||||||
|
|
||||||
error: unconstrained generic constant
|
|
||||||
--> $DIR/issue-83765.rs:100:24
|
|
||||||
|
|
|
||||||
LL | self.reference.bget(index).map(&self.closure)
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
|
|
||||||
note: required by a bound in `Broadcastable::bget`
|
|
||||||
--> $DIR/issue-83765.rs:23:35
|
|
||||||
|
|
|
||||||
LL | fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>;
|
|
||||||
| ^^^^^^^^^ required by this bound in `Broadcastable::bget`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/issue-83765.rs:100:29
|
|
||||||
|
|
|
||||||
LL | self.reference.bget(index).map(&self.closure)
|
|
||||||
| ^^^^^ expected `Self::DIM`, found `DIM`
|
|
||||||
|
|
|
||||||
= note: expected constant `Self::DIM`
|
|
||||||
found constant `DIM`
|
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue