]> git.lizzy.rs Git - rust.git/commitdiff
fix expected/found order on impl trait projection mismatch
authorSNCPlay42 <SNCPlay42@gmail.com>
Fri, 8 Jan 2021 22:07:49 +0000 (22:07 +0000)
committerSNCPlay42 <SNCPlay42@gmail.com>
Tue, 16 Mar 2021 16:55:11 +0000 (16:55 +0000)
13 files changed:
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/ty/error.rs
compiler/rustc_trait_selection/src/opaque_types.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
src/test/ui/generator/type-mismatch-signature-deduction.stderr
src/test/ui/impl-trait/bound-normalization-fail.stderr
src/test/ui/impl-trait/equality2.stderr
src/test/ui/impl-trait/issues/issue-70877.full_tait.stderr
src/test/ui/impl-trait/issues/issue-70877.min_tait.stderr
src/test/ui/type-alias-impl-trait/issue-63279.full_tait.stderr
src/test/ui/type-alias-impl-trait/issue-63279.min_tait.stderr

index 0bd0a701fb2e7aa2ebd2693130e377fe7ac0b858..3650866c007a1618388496021a25ab8e219e5b56 100644 (file)
@@ -323,6 +323,9 @@ pub enum ObligationCauseCode<'tcx> {
 
     /// #[feature(trivial_bounds)] is not enabled
     TrivialBound,
+
+    /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
+    OpaqueType,
 }
 
 impl ObligationCauseCode<'_> {
index f19cc99844926a0d0ce821c8698c2d503695fa26..8ff84b0e743d2c556ccc06f12637893ef0ad673c 100644 (file)
@@ -509,13 +509,18 @@ fn foo(&self, x: T) -> T { x }
                             "consider constraining the associated type `{}` to `{}`",
                             values.found, values.expected,
                         );
-                        if !self.suggest_constraint(
+                        if !(self.suggest_constraining_opaque_associated_type(
+                            db,
+                            &msg,
+                            proj_ty,
+                            values.expected,
+                        ) || self.suggest_constraint(
                             db,
                             &msg,
                             body_owner_def_id,
                             proj_ty,
                             values.expected,
-                        ) {
+                        )) {
                             db.help(&msg);
                             db.note(
                                 "for more information, visit \
@@ -699,20 +704,7 @@ fn expected_projection(
             }
         }
 
-        if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
-            // When the expected `impl Trait` is not defined in the current item, it will come from
-            // a return type. This can occur when dealing with `TryStream` (#71035).
-            if self.constrain_associated_type_structured_suggestion(
-                db,
-                self.def_span(def_id),
-                &assoc,
-                proj_ty.trait_ref_and_own_substs(self).1,
-                values.found,
-                &msg,
-            ) {
-                return;
-            }
-        }
+        self.suggest_constraining_opaque_associated_type(db, &msg, proj_ty, values.found);
 
         if self.point_at_associated_type(db, body_owner_def_id, values.found) {
             return;
@@ -750,6 +742,30 @@ fn foo(&self) -> Self::T { String::new() }
         }
     }
 
+    /// When the expected `impl Trait` is not defined in the current item, it will come from
+    /// a return type. This can occur when dealing with `TryStream` (#71035).
+    fn suggest_constraining_opaque_associated_type(
+        self,
+        db: &mut DiagnosticBuilder<'_>,
+        msg: &str,
+        proj_ty: &ty::ProjectionTy<'tcx>,
+        ty: Ty<'tcx>,
+    ) -> bool {
+        let assoc = self.associated_item(proj_ty.item_def_id);
+        if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
+            self.constrain_associated_type_structured_suggestion(
+                db,
+                self.def_span(def_id),
+                &assoc,
+                proj_ty.trait_ref_and_own_substs(self).1,
+                ty,
+                &msg,
+            )
+        } else {
+            false
+        }
+    }
+
     fn point_at_methods_that_satisfy_associated_type(
         self,
         db: &mut DiagnosticBuilder<'_>,
index d6a585e626c482e811ffb68796c0f8ee3eda9dbd..186256101e4888bc1188c53eab7d5980b2f16370 100644 (file)
@@ -1171,7 +1171,7 @@ fn fold_opaque_ty(
             // This also instantiates nested instances of `impl Trait`.
             let predicate = self.instantiate_opaque_types_in_map(predicate);
 
-            let cause = traits::ObligationCause::new(span, self.body_id, traits::MiscObligation);
+            let cause = traits::ObligationCause::new(span, self.body_id, traits::OpaqueType);
 
             // Require that the predicate holds for the concrete type.
             debug!("instantiate_opaque_types: predicate={:?}", predicate);
index a3faf4cb7d4c19d1f2eb457087368fbcbfd56618..5de4fb1ce8c6aadc95cd51934de10e160f911ebd 100644 (file)
@@ -1194,6 +1194,7 @@ fn report_projection_error(
                     ObligationCauseCode::ItemObligation(_)
                         | ObligationCauseCode::BindingObligation(_, _)
                         | ObligationCauseCode::ObjectCastObligation(_)
+                        | ObligationCauseCode::OpaqueType
                 );
 
                 if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
index c1b105f1d8489a666e975a1f2993a97ce105bbcb..6292413d7bd39c44f9c6c07becfc3b1afea7344c 100644 (file)
@@ -1840,6 +1840,7 @@ fn note_obligation_cause_code<T>(
             | ObligationCauseCode::MethodReceiver
             | ObligationCauseCode::ReturnNoExpression
             | ObligationCauseCode::UnifyReceiver(..)
+            | ObligationCauseCode::OpaqueType
             | ObligationCauseCode::MiscObligation => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
index b0e9e33a6c38ecffeda0cbef786f32659c24878f..89e05b61fc9d89a8097cee7bbbfc05e6d94c10b1 100644 (file)
@@ -2,13 +2,13 @@ error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
   --> $DIR/impl-trait-return-missing-constraint.rs:25:13
    |
 LL | fn bar() -> impl Bar {
-   |             -------- the expected opaque type
+   |             -------- the found opaque type
 ...
 LL | fn baz() -> impl Bar<Item = i32> {
-   |             ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
+   |             ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type
    |
-   = note: expected associated type `<impl Bar as Foo>::Item`
-                         found type `i32`
+   = note:         expected type `i32`
+           found associated type `<impl Bar as Foo>::Item`
 help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
    |
 LL | fn bar() -> impl Bar<Item = i32> {
index 30e23ea8f650c0c64fd2226697a399e585ae891b..3f1f33a3b123f40361e4d54bcbc01667e044a307 100644 (file)
@@ -16,10 +16,10 @@ error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-
   --> $DIR/type-mismatch-signature-deduction.rs:5:13
    |
 LL | fn foo() -> impl Generator<Return = i32> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `i32`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found enum `Result`
    |
-   = note: expected enum `Result<{integer}, _>`
-              found type `i32`
+   = note: expected type `i32`
+              found enum `Result<{integer}, _>`
 
 error: aborting due to 2 previous errors
 
index a7d06c71663de259f4d492da884c8df32a98f423..6958cd97a4ac0aeae14031c65d5772563dc0e107 100644 (file)
@@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as imp
   --> $DIR/bound-normalization-fail.rs:27:32
    |
 LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
    |
-   = note:         expected type `()`
-           found associated type `<T as impl_trait::Trait>::Assoc`
+   = note: expected associated type `<T as impl_trait::Trait>::Assoc`
+                         found type `()`
 help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
    |
 LL |     fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
@@ -30,10 +30,10 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lif
   --> $DIR/bound-normalization-fail.rs:43:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
    |
-   = note:         expected type `()`
-           found associated type `<T as lifetimes::Trait<'static>>::Assoc`
+   = note: expected associated type `<T as lifetimes::Trait<'static>>::Assoc`
+                         found type `()`
 help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
    |
 LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
index 1443b76048b324402385f00e6e41a86a5cb2e27e..3318866c52cf95e3ae1930f70e2c252f4958b3e0 100644 (file)
@@ -35,8 +35,10 @@ LL |     let _: i32 = Leak::leak(hide(0_i32));
    |
    = note:         expected type `i32`
            found associated type `<impl Foo as Leak>::T`
-   = help: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
-   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+help: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
+   |
+LL | fn hide<T: Foo>(x: T) -> impl Foo<T = i32> {
+   |                                  ^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/equality2.rs:38:10
index bd4d4fdf2a6b4a7c51d66d9c124bc53048e314e9..8e42b9d46db390b9d61f6e6ee7e6e764f7f33adb 100644 (file)
@@ -2,13 +2,13 @@ error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'
   --> $DIR/issue-70877.rs:11:12
    |
 LL | type FooRet = impl std::fmt::Debug;
-   |               -------------------- the expected opaque type
+   |               -------------------- the found opaque type
 ...
 LL | type Foo = impl Iterator<Item = FooItem>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found enum `Option`
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Option`, found opaque type
    |
-   = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
-              found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+   = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+              found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
 
 error: aborting due to previous error
 
index bd4d4fdf2a6b4a7c51d66d9c124bc53048e314e9..8e42b9d46db390b9d61f6e6ee7e6e764f7f33adb 100644 (file)
@@ -2,13 +2,13 @@ error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'
   --> $DIR/issue-70877.rs:11:12
    |
 LL | type FooRet = impl std::fmt::Debug;
-   |               -------------------- the expected opaque type
+   |               -------------------- the found opaque type
 ...
 LL | type Foo = impl Iterator<Item = FooItem>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found enum `Option`
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Option`, found opaque type
    |
-   = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
-              found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+   = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+              found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
 
 error: aborting due to previous error
 
index f544f61df97f387b97ac72cbd512b239a37b0de7..53a0016c08eb56580d1af2c6360837089570d041 100644 (file)
@@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:11:5: 11:28
   --> $DIR/issue-63279.rs:8:16
    |
 LL | type Closure = impl FnOnce();
-   |                ^^^^^^^^^^^^^ expected opaque type, found `()`
+   |                ^^^^^^^^^^^^^ expected `()`, found opaque type
    |
-   = note: expected opaque type `impl FnOnce<()>`
-                found unit type `()`
+   = note: expected unit type `()`
+            found opaque type `impl FnOnce<()>`
 
 error: aborting due to previous error; 1 warning emitted
 
index bdf414d0badd3d1abbc6ce9986b8a5b952e3fa25..be386ab90ea007ebb552be202338f7fb7203860b 100644 (file)
@@ -11,10 +11,10 @@ error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:11:5: 11:28
   --> $DIR/issue-63279.rs:8:16
    |
 LL | type Closure = impl FnOnce();
-   |                ^^^^^^^^^^^^^ expected opaque type, found `()`
+   |                ^^^^^^^^^^^^^ expected `()`, found opaque type
    |
-   = note: expected opaque type `impl FnOnce<()>`
-                found unit type `()`
+   = note: expected unit type `()`
+            found opaque type `impl FnOnce<()>`
 
 error: aborting due to 2 previous errors