handle assoc consts in fulfill ConstEquate

This commit is contained in:
Boxy 2022-11-15 22:53:30 +00:00 committed by kadmin
parent d75cd5c051
commit 0ae3c5c609
8 changed files with 90 additions and 176 deletions

View File

@ -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;

View File

@ -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() {}

View File

@ -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);
}

View File

@ -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

View File

@ -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() {}

View File

@ -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`.

View File

@ -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
}
}

View File

@ -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`.