handle assoc consts in fulfill ConstEquate
This commit is contained in:
parent
d75cd5c051
commit
0ae3c5c609
@ -457,41 +457,45 @@ fn process_obligation(
|
||||
tcx.features().generic_const_exprs,
|
||||
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
|
||||
);
|
||||
debug!(?c1, ?c2, "equating consts");
|
||||
// FIXME: we probably should only try to unify abstract constants
|
||||
// if the constants depend on generic parameters.
|
||||
//
|
||||
// Let's just see where this breaks :shrug:
|
||||
match (c1.kind(), c2.kind()) {
|
||||
(ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) => {
|
||||
// FIXME: remove
|
||||
use rustc_hir::def::DefKind;
|
||||
if tcx.def_kind(a.def.did) == DefKind::AssocConst
|
||||
|| tcx.def_kind(b.def.did) == DefKind::AssocConst
|
||||
{
|
||||
// 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),
|
||||
),
|
||||
);
|
||||
}
|
||||
{
|
||||
let c1 =
|
||||
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1) { a } else { c1 };
|
||||
let c2 =
|
||||
if let Ok(Some(b)) = tcx.expand_abstract_consts(c2) { b } else { c2 };
|
||||
debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
|
||||
|
||||
if let Ok(Some(a)) = tcx.expand_abstract_consts(c1)
|
||||
&& let Ok(Some(b)) = tcx.expand_abstract_consts(c2)
|
||||
&& a.ty() == b.ty()
|
||||
&& let Ok(new_obligations) = infcx
|
||||
use rustc_hir::def::DefKind;
|
||||
use ty::ConstKind::Unevaluated;
|
||||
match (c1.kind(), c2.kind()) {
|
||||
(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)
|
||||
.eq(a, b)
|
||||
.trace(c1, c2)
|
||||
.eq(a.substs, b.substs)
|
||||
{
|
||||
return ProcessResult::Changed(mk_pending(
|
||||
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;
|
||||
|
@ -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 ())>
|
||||
) -> &'static Foo<fn(&'static ())> {
|
||||
v
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let y = covariant(&Foo([], PhantomData)); //~ ERROR mismatched types
|
||||
let y = covariant(&Foo([], PhantomData));
|
||||
println!("{:?}", y.0);
|
||||
}
|
||||
|
@ -13,13 +13,13 @@ LL | impl SadBee for fn(&'static ()) {
|
||||
= note: `#[warn(coherence_leak_check)]` on by default
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/invariant.rs:31:28
|
||||
--> $DIR/invariant.rs:27:5
|
||||
|
|
||||
LL | let y = covariant(&Foo([], PhantomData));
|
||||
| ^^ expected `<_ as SadBee>::ASSOC`, found `<for<'a> fn(&'a ()) as SadBee>::ASSOC`
|
||||
LL | v
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected constant `<_ as SadBee>::ASSOC`
|
||||
found constant `<for<'a> fn(&'a ()) as SadBee>::ASSOC`
|
||||
= note: expected reference `&Foo<fn(&())>`
|
||||
found reference `&Foo<for<'a> fn(&'a ())>`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
|
@ -15,9 +15,9 @@ impl Foo for u8 {
|
||||
|
||||
pub fn bar() {
|
||||
let _: u8 = foo([0; 1]);
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
|
||||
let _ = foo([0; 1]);
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,12 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-83249.rs:17:21
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-83249.rs:19:9
|
||||
|
|
||||
LL | let _: u8 = foo([0; 1]);
|
||||
| ^^^^^^ expected `<_ as Foo>::N`, found `<u8 as Foo>::N`
|
||||
LL | let _ = foo([0; 1]);
|
||||
| ^
|
||||
|
|
||||
= note: expected constant `<_ as Foo>::N`
|
||||
found constant `<u8 as Foo>::N`
|
||||
help: consider giving this pattern a type
|
||||
|
|
||||
LL | let _: _ = foo([0; 1]);
|
||||
| +++
|
||||
|
||||
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 {
|
||||
const DIM: usize;
|
||||
//~^ ERROR cycle detected when resolving instance
|
||||
// FIXME Given the current state of the compiler its expected that we cycle here,
|
||||
// but the cycle is still wrong.
|
||||
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> {
|
||||
fn size(&self) -> [usize; DIM] {
|
||||
//~^ ERROR method not compatible
|
||||
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> {
|
||||
type Element = T::Element;
|
||||
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
||||
//~^ ERROR method not compatible
|
||||
assert!(DIM >= T::DIM);
|
||||
if !self.inbounds(index) {
|
||||
//~^ ERROR mismatched types
|
||||
//~^^ ERROR unconstrained generic constant
|
||||
return None;
|
||||
}
|
||||
let size = self.size();
|
||||
//~^ ERROR unconstrained generic constant
|
||||
let newindex: [usize; T::DIM] = Default::default();
|
||||
//~^ ERROR the trait bound
|
||||
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>
|
||||
{
|
||||
fn size(&self) -> [usize; DIM] {
|
||||
//~^ ERROR method not compatible
|
||||
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;
|
||||
fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
|
||||
//~^ ERROR method not compatible
|
||||
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
|
||||
--> $DIR/issue-83765.rs:49:5
|
||||
error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`
|
||||
--> $DIR/issue-83765.rs:5:5
|
||||
|
|
||||
LL | fn size(&self) -> [usize; DIM] {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
|
||||
LL | const DIM: usize;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected constant `Self::DIM`
|
||||
found constant `DIM`
|
||||
note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
|
||||
--> $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
|
||||
--> $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: aborting due to previous error
|
||||
|
||||
error[E0308]: method not compatible with trait
|
||||
--> $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`.
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
Loading…
Reference in New Issue
Block a user