about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2024-03-01 17:19:16 +0100
committerLukas Markeffsky <@>2024-03-04 21:06:52 +0100
commitaa55f6daa2c83020a271077bb15590755f4119d9 (patch)
tree76fcee965873411d942db33f970411bc00721a18
parent443c81626103e3f6c03e9ea681c81a3f737312e8 (diff)
downloadrust-aa55f6daa2c83020a271077bb15590755f4119d9.tar.gz
rust-aa55f6daa2c83020a271077bb15590755f4119d9.zip
suppress fulfillment errors for super projections
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs69
-rw-r--r--tests/ui/issues/issue-33941.rs1
-rw-r--r--tests/ui/issues/issue-33941.stderr12
-rw-r--r--tests/ui/trait-bounds/super-assoc-mismatch.rs5
-rw-r--r--tests/ui/trait-bounds/super-assoc-mismatch.stderr121
5 files changed, 48 insertions, 160 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 62933bce76b..129ddb089bd 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -1389,38 +1389,45 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             return true;
         }
 
-        // FIXME: It should be possible to deal with `ForAll` in a cleaner way.
-        let bound_error = error.kind();
-        let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) {
-            (
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)),
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(error)),
-            ) => (cond, bound_error.rebind(error)),
-            _ => {
-                // FIXME: make this work in other cases too.
-                return false;
-            }
-        };
-
-        for pred in elaborate(self.tcx, std::iter::once(cond)) {
-            let bound_predicate = pred.kind();
-            if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(implication)) =
-                bound_predicate.skip_binder()
-            {
-                let error = error.to_poly_trait_ref();
-                let implication = bound_predicate.rebind(implication.trait_ref);
-                // FIXME: I'm just not taking associated types at all here.
-                // Eventually I'll need to implement param-env-aware
-                // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
-                let param_env = ty::ParamEnv::empty();
-                if self.can_sub(param_env, error, implication) {
-                    debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
-                    return true;
-                }
-            }
+        if let Some(error) = error.to_opt_poly_trait_pred() {
+            elaborate(self.tcx, std::iter::once(cond))
+                .filter_map(|implied| implied.to_opt_poly_trait_pred())
+                .any(|implied| {
+                    if error.polarity() != implied.polarity() {
+                        return false;
+                    }
+                    let error = error.to_poly_trait_ref();
+                    let implied = implied.to_poly_trait_ref();
+                    // FIXME: I'm just not taking associated types at all here.
+                    // Eventually I'll need to implement param-env-aware
+                    // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
+                    let param_env = ty::ParamEnv::empty();
+                    let is_implied = self.can_sub(param_env, error, implied);
+                    if is_implied {
+                        debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
+                    }
+                    is_implied
+                })
+        } else if let Some(error) = error.to_opt_poly_projection_pred() {
+            self.enter_forall(error, |error| {
+                elaborate(self.tcx, std::iter::once(cond))
+                    .filter_map(|implied| implied.to_opt_poly_projection_pred())
+                    .any(|implied| {
+                        self.enter_forall(implied, |implied| {
+                            let param_env = ty::ParamEnv::empty();
+                            let is_implied =
+                                self.can_eq(param_env, error.projection_ty, implied.projection_ty)
+                                    && self.can_eq(param_env, error.term, implied.term);
+                            if is_implied {
+                                debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implied);
+                            }
+                            is_implied
+                        })
+                    })
+            })
+        } else {
+            false
         }
-
-        false
     }
 
     #[instrument(skip(self), level = "debug")]
diff --git a/tests/ui/issues/issue-33941.rs b/tests/ui/issues/issue-33941.rs
index 0ad7cbe8efc..7b5be30834b 100644
--- a/tests/ui/issues/issue-33941.rs
+++ b/tests/ui/issues/issue-33941.rs
@@ -5,5 +5,4 @@ use std::collections::HashMap;
 fn main() {
     for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
     //~^ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
-    //~| ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
 }
diff --git a/tests/ui/issues/issue-33941.stderr b/tests/ui/issues/issue-33941.stderr
index e7f4a4fa004..f1b6b6ba17e 100644
--- a/tests/ui/issues/issue-33941.stderr
+++ b/tests/ui/issues/issue-33941.stderr
@@ -27,16 +27,6 @@ LL |     for _ in HashMap::new().iter().cloned() {}
    = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
    = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`
 
-error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
-  --> $DIR/issue-33941.rs:6:14
-   |
-LL |     for _ in HashMap::new().iter().cloned() {}
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(&_, &_)`, found `&_`
-   |
-   = note:  expected tuple `(&_, &_)`
-           found reference `&_`
-   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/trait-bounds/super-assoc-mismatch.rs b/tests/ui/trait-bounds/super-assoc-mismatch.rs
index b701f0b3f88..00a9df35b00 100644
--- a/tests/ui/trait-bounds/super-assoc-mismatch.rs
+++ b/tests/ui/trait-bounds/super-assoc-mismatch.rs
@@ -9,12 +9,10 @@ trait Sub: Super<Assoc = u16> {}
 trait BoundOnSelf: Sub {}
 impl BoundOnSelf for () {}
 //~^ ERROR the trait bound `(): Sub` is not satisfied
-//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
 
 trait BoundOnParam<T: Sub> {}
 impl BoundOnParam<()> for () {}
 //~^ ERROR the trait bound `(): Sub` is not satisfied
-//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
 
 trait BoundOnAssoc {
     type Assoc: Sub;
@@ -22,7 +20,6 @@ trait BoundOnAssoc {
 impl BoundOnAssoc for () {
     type Assoc = ();
     //~^ ERROR the trait bound `(): Sub` is not satisfied
-    //~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
 }
 
 trait BoundOnGat where Self::Assoc<u8>: Sub {
@@ -31,11 +28,9 @@ trait BoundOnGat where Self::Assoc<u8>: Sub {
 impl BoundOnGat for u8 {
     type Assoc<T> = ();
     //~^ ERROR the trait bound `(): Sub` is not satisfied
-    //~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
 }
 
 fn trivial_bound() where (): Sub {}
 //~^ ERROR the trait bound `(): Sub` is not satisfied
-//~| ERROR type mismatch resolving `<() as Super>::Assoc == u16`
 
 fn main() {}
diff --git a/tests/ui/trait-bounds/super-assoc-mismatch.stderr b/tests/ui/trait-bounds/super-assoc-mismatch.stderr
index bf19dd45193..0ce0b66cbf9 100644
--- a/tests/ui/trait-bounds/super-assoc-mismatch.stderr
+++ b/tests/ui/trait-bounds/super-assoc-mismatch.stderr
@@ -15,30 +15,8 @@ note: required by a bound in `BoundOnSelf`
 LL | trait BoundOnSelf: Sub {}
    |                    ^^^ required by this bound in `BoundOnSelf`
 
-error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
-  --> $DIR/super-assoc-mismatch.rs:10:22
-   |
-LL | impl BoundOnSelf for () {}
-   |                      ^^ type mismatch resolving `<() as Super>::Assoc == u16`
-   |
-note: expected this to be `u16`
-  --> $DIR/super-assoc-mismatch.rs:5:18
-   |
-LL |     type Assoc = u8;
-   |                  ^^
-note: required for `()` to implement `Sub`
-  --> $DIR/super-assoc-mismatch.rs:7:7
-   |
-LL | trait Sub: Super<Assoc = u16> {}
-   |       ^^^
-note: required by a bound in `BoundOnSelf`
-  --> $DIR/super-assoc-mismatch.rs:9:20
-   |
-LL | trait BoundOnSelf: Sub {}
-   |                    ^^^ required by this bound in `BoundOnSelf`
-
 error[E0277]: the trait bound `(): Sub` is not satisfied
-  --> $DIR/super-assoc-mismatch.rs:15:27
+  --> $DIR/super-assoc-mismatch.rs:14:27
    |
 LL | impl BoundOnParam<()> for () {}
    |                           ^^ the trait `Sub` is not implemented for `()`
@@ -49,35 +27,13 @@ help: this trait has no implementations, consider adding one
 LL | trait Sub: Super<Assoc = u16> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `BoundOnParam`
-  --> $DIR/super-assoc-mismatch.rs:14:23
-   |
-LL | trait BoundOnParam<T: Sub> {}
-   |                       ^^^ required by this bound in `BoundOnParam`
-
-error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
-  --> $DIR/super-assoc-mismatch.rs:15:27
-   |
-LL | impl BoundOnParam<()> for () {}
-   |                           ^^ type mismatch resolving `<() as Super>::Assoc == u16`
-   |
-note: expected this to be `u16`
-  --> $DIR/super-assoc-mismatch.rs:5:18
-   |
-LL |     type Assoc = u8;
-   |                  ^^
-note: required for `()` to implement `Sub`
-  --> $DIR/super-assoc-mismatch.rs:7:7
-   |
-LL | trait Sub: Super<Assoc = u16> {}
-   |       ^^^
-note: required by a bound in `BoundOnParam`
-  --> $DIR/super-assoc-mismatch.rs:14:23
+  --> $DIR/super-assoc-mismatch.rs:13:23
    |
 LL | trait BoundOnParam<T: Sub> {}
    |                       ^^^ required by this bound in `BoundOnParam`
 
 error[E0277]: the trait bound `(): Sub` is not satisfied
-  --> $DIR/super-assoc-mismatch.rs:23:18
+  --> $DIR/super-assoc-mismatch.rs:21:18
    |
 LL |     type Assoc = ();
    |                  ^^ the trait `Sub` is not implemented for `()`
@@ -88,35 +44,13 @@ help: this trait has no implementations, consider adding one
 LL | trait Sub: Super<Assoc = u16> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `BoundOnAssoc::Assoc`
-  --> $DIR/super-assoc-mismatch.rs:20:17
-   |
-LL |     type Assoc: Sub;
-   |                 ^^^ required by this bound in `BoundOnAssoc::Assoc`
-
-error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
-  --> $DIR/super-assoc-mismatch.rs:23:18
-   |
-LL |     type Assoc = ();
-   |                  ^^ type mismatch resolving `<() as Super>::Assoc == u16`
-   |
-note: expected this to be `u16`
-  --> $DIR/super-assoc-mismatch.rs:5:18
-   |
-LL |     type Assoc = u8;
-   |                  ^^
-note: required for `<() as BoundOnAssoc>::Assoc` to implement `Sub`
-  --> $DIR/super-assoc-mismatch.rs:7:7
-   |
-LL | trait Sub: Super<Assoc = u16> {}
-   |       ^^^
-note: required by a bound in `BoundOnAssoc::Assoc`
-  --> $DIR/super-assoc-mismatch.rs:20:17
+  --> $DIR/super-assoc-mismatch.rs:18:17
    |
 LL |     type Assoc: Sub;
    |                 ^^^ required by this bound in `BoundOnAssoc::Assoc`
 
 error[E0277]: the trait bound `(): Sub` is not satisfied
-  --> $DIR/super-assoc-mismatch.rs:32:21
+  --> $DIR/super-assoc-mismatch.rs:29:21
    |
 LL |     type Assoc<T> = ();
    |                     ^^ the trait `Sub` is not implemented for `()`, which is required by `<u8 as BoundOnGat>::Assoc<u8>: Sub`
@@ -127,35 +61,13 @@ help: this trait has no implementations, consider adding one
 LL | trait Sub: Super<Assoc = u16> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `BoundOnGat`
-  --> $DIR/super-assoc-mismatch.rs:28:41
-   |
-LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
-   |                                         ^^^ required by this bound in `BoundOnGat`
-
-error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
-  --> $DIR/super-assoc-mismatch.rs:32:21
-   |
-LL |     type Assoc<T> = ();
-   |                     ^^ type mismatch resolving `<() as Super>::Assoc == u16`
-   |
-note: expected this to be `u16`
-  --> $DIR/super-assoc-mismatch.rs:5:18
-   |
-LL |     type Assoc = u8;
-   |                  ^^
-note: required for `<u8 as BoundOnGat>::Assoc<u8>` to implement `Sub`
-  --> $DIR/super-assoc-mismatch.rs:7:7
-   |
-LL | trait Sub: Super<Assoc = u16> {}
-   |       ^^^
-note: required by a bound in `BoundOnGat`
-  --> $DIR/super-assoc-mismatch.rs:28:41
+  --> $DIR/super-assoc-mismatch.rs:25:41
    |
 LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
    |                                         ^^^ required by this bound in `BoundOnGat`
 
 error[E0277]: the trait bound `(): Sub` is not satisfied
-  --> $DIR/super-assoc-mismatch.rs:37:26
+  --> $DIR/super-assoc-mismatch.rs:33:26
    |
 LL | fn trivial_bound() where (): Sub {}
    |                          ^^^^^^^ the trait `Sub` is not implemented for `()`
@@ -168,21 +80,6 @@ LL | trait Sub: Super<Assoc = u16> {}
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-error[E0271]: type mismatch resolving `<() as Super>::Assoc == u16`
-  --> $DIR/super-assoc-mismatch.rs:37:26
-   |
-LL | fn trivial_bound() where (): Sub {}
-   |                          ^^^^^^^ type mismatch resolving `<() as Super>::Assoc == u16`
-   |
-note: expected this to be `u8`
-  --> $DIR/super-assoc-mismatch.rs:5:18
-   |
-LL |     type Assoc = u8;
-   |                  ^^
-   = help: see issue #48214
-   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
-
-error: aborting due to 10 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.