about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBoxy <supbscripter@gmail.com>2022-11-15 22:53:30 +0000
committerkadmin <julianknodt@gmail.com>2022-11-25 09:28:43 +0000
commit0ae3c5c60964bdfb95a524e86d7804e97ca6ceb8 (patch)
tree25bf3c72b3da6124047415047165423376488d36
parentd75cd5c05111256a3c0d82d0df727cb2b52680b7 (diff)
downloadrust-0ae3c5c60964bdfb95a524e86d7804e97ca6ceb8.tar.gz
rust-0ae3c5c60964bdfb95a524e86d7804e97ca6ceb8.zip
handle assoc consts in fulfill `ConstEquate`
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs50
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs27
-rw-r--r--src/test/ui/const-generics/invariant.rs3
-rw-r--r--src/test/ui/const-generics/invariant.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-83249.rs4
-rw-r--r--src/test/ui/const-generics/issues/issue-83249.stderr16
-rw-r--r--src/test/ui/const-generics/issues/issue-83765.rs13
-rw-r--r--src/test/ui/const-generics/issues/issue-83765.stderr139
8 files changed, 88 insertions, 174 deletions
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
+                    {
+                        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);
+
+                        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 =>
                             {
-                                // 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)
-                                && let Ok(Some(b)) = tcx.expand_abstract_consts(c2)
-                                && a.ty() == b.ty() 
-                                && let Ok(new_obligations) = infcx
+                                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<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() {}
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<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);
 }
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 `<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
 
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<T: 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 `<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`.
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<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
     }
 }
 
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 `<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`
-
-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[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
+note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
+  --> $DIR/issue-83765.rs:4:1
    |
-LL |         self.reference.bget(index).map(&self.closure)
-   |                             ^^^^^ expected `Self::DIM`, found `DIM`
+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
    |
-   = note: expected constant `Self::DIM`
-              found constant `DIM`
+LL | trait TensorDimension {
+   | ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 12 previous errors
+error: aborting due to previous error
 
-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`.