diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 806e031a4bb..1fd0926fec9 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -457,41 +457,45 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { 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; diff --git a/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs new file mode 100644 index 00000000000..e8f89cb1aa2 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs @@ -0,0 +1,27 @@ +// check-pass +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Trait { + const ASSOC: usize; +} +impl Trait for T { + const ASSOC: usize = std::mem::size_of::(); +} + +struct Foo([u8; T::ASSOC]) +where + [(); T::ASSOC]:; + +fn bar() +where + [(); T::ASSOC]:, +{ + let _: Foo = Foo::<_>(make()); +} + +fn make() -> ! { + todo!() +} + +fn main() {} diff --git a/src/test/ui/const-generics/invariant.rs b/src/test/ui/const-generics/invariant.rs index f7ab8b83cb6..39d658be67d 100644 --- a/src/test/ui/const-generics/invariant.rs +++ b/src/test/ui/const-generics/invariant.rs @@ -25,9 +25,10 @@ fn covariant( v: &'static Foo fn(&'a ())> ) -> &'static Foo { v + //~^ ERROR mismatched types } fn main() { - let y = covariant(&Foo([], PhantomData)); //~ ERROR mismatched types + let y = covariant(&Foo([], PhantomData)); println!("{:?}", y.0); } diff --git a/src/test/ui/const-generics/invariant.stderr b/src/test/ui/const-generics/invariant.stderr index 9f43d77c805..aabe4c93b36 100644 --- a/src/test/ui/const-generics/invariant.stderr +++ b/src/test/ui/const-generics/invariant.stderr @@ -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 ` fn(&'a ()) as SadBee>::ASSOC` +LL | v + | ^ one type is more general than the other | - = note: expected constant `<_ as SadBee>::ASSOC` - found constant ` fn(&'a ()) as SadBee>::ASSOC` + = note: expected reference `&Foo` + found reference `&Foo fn(&'a ())>` error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-83249.rs b/src/test/ui/const-generics/issues/issue-83249.rs index 43dc94b9ced..a16b28253b5 100644 --- a/src/test/ui/const-generics/issues/issue-83249.rs +++ b/src/test/ui/const-generics/issues/issue-83249.rs @@ -15,9 +15,9 @@ fn foo(_: [u8; T::N]) -> T { pub fn bar() { let _: u8 = foo([0; 1]); - //~^ ERROR mismatched types - + let _ = foo([0; 1]); + //~^ ERROR type annotations needed } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr index d55e1ea5900..362b8554b2f 100644 --- a/src/test/ui/const-generics/issues/issue-83249.stderr +++ b/src/test/ui/const-generics/issues/issue-83249.stderr @@ -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 `::N` +LL | let _ = foo([0; 1]); + | ^ | - = note: expected constant `<_ as Foo>::N` - found constant `::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`. diff --git a/src/test/ui/const-generics/issues/issue-83765.rs b/src/test/ui/const-generics/issues/issue-83765.rs index cf59763675b..71c164ab0a5 100644 --- a/src/test/ui/const-generics/issues/issue-83765.rs +++ b/src/test/ui/const-generics/issues/issue-83765.rs @@ -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 { - //~^ 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 { - //~^ ERROR method not compatible self.reference.bget(index).map(&self.closure) - //~^ ERROR unconstrained generic constant - //~| ERROR mismatched types } } diff --git a/src/test/ui/const-generics/issues/issue-83765.stderr b/src/test/ui/const-generics/issues/issue-83765.stderr index f84fd014635..d7b2b006c2a 100644 --- a/src/test/ui/const-generics/issues/issue-83765.stderr +++ b/src/test/ui/const-generics/issues/issue-83765.stderr @@ -1,130 +1,21 @@ -error[E0308]: method not compatible with trait - --> $DIR/issue-83765.rs:49:5 +error[E0391]: cycle detected when resolving instance `::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 `::DIM, DIM> as TensorDimension>`... + --> $DIR/issue-83765.rs:4:1 + | +LL | trait TensorDimension { + | ^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires resolving instance `::DIM, DIM> as TensorDimension>::DIM`, completing the cycle +note: cycle used when computing candidate for ` 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 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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; - | ^^^^^^^^^ 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`.