about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-03-11 16:57:18 +0000
committerMichael Goulet <michael@errs.io>2024-03-14 12:17:00 -0400
commit04524c8f6aef8a8a1b3b80edb93815e86caeddfa (patch)
tree29b00f7432590ffb3deab9325a13ed6cfab53430
parentc2fbe404d21572a04dabc6a0e23eb3ab367832ad (diff)
downloadrust-04524c8f6aef8a8a1b3b80edb93815e86caeddfa.tar.gz
rust-04524c8f6aef8a8a1b3b80edb93815e86caeddfa.zip
Consolidate WF for aliases
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs28
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr18
-rw-r--r--tests/ui/lifetimes/issue-76168-hr-outlives-3.rs1
-rw-r--r--tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr23
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr23
6 files changed, 68 insertions, 26 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index f89daf033f6..64f02bfd321 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -164,7 +164,7 @@ pub fn clause_obligations<'tcx>(
             wf.compute(ty.into());
         }
         ty::ClauseKind::Projection(t) => {
-            wf.compute_projection(t.projection_ty);
+            wf.compute_alias(t.projection_ty);
             wf.compute(match t.term.unpack() {
                 ty::TermKind::Ty(ty) => ty.into(),
                 ty::TermKind::Const(c) => c.into(),
@@ -436,9 +436,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
         }
     }
 
-    /// Pushes the obligations required for `trait_ref::Item` to be WF
+    /// Pushes the obligations required for an alias (except inherent) to be WF
     /// into `self.out`.
-    fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) {
+    fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) {
         // A projection is well-formed if
         //
         // (a) its predicates hold (*)
@@ -466,6 +466,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
         self.compute_projection_args(data.args);
     }
 
+    /// Pushes the obligations required for an inherent alias to be WF
+    /// into `self.out`.
+    // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`.
     fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
         // An inherent projection is well-formed if
         //
@@ -688,8 +691,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 // Simple cases that are WF if their type args are WF.
             }
 
-            ty::Alias(ty::Projection, data) => {
-                self.compute_projection(data);
+            ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => {
+                self.compute_alias(data);
                 return; // Subtree handled by compute_projection.
             }
             ty::Alias(ty::Inherent, data) => {
@@ -791,21 +794,6 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 // types appearing in the fn signature.
             }
 
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                // All of the requirements on type parameters
-                // have already been checked for `impl Trait` in
-                // return position. We do need to check type-alias-impl-trait though.
-                if self.tcx().is_type_alias_impl_trait(def_id) {
-                    let obligations = self.nominal_obligations(def_id, args);
-                    self.out.extend(obligations);
-                }
-            }
-
-            ty::Alias(ty::Weak, ty::AliasTy { def_id, args, .. }) => {
-                let obligations = self.nominal_obligations(def_id, args);
-                self.out.extend(obligations);
-            }
-
             ty::Dynamic(data, r, _) => {
                 // WfObject
                 //
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
index ff265e576b9..84bc39d9263 100644
--- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
@@ -9,6 +9,7 @@ impl Foo<char> for Bar {
         //~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277]
         //~| ERROR: the trait bound `Bar: Foo<u8>` is not satisfied [E0277]
         //~| ERROR: impl has stricter requirements than trait
+        //~| ERROR: the trait bound `F2: Foo<u8>` is not satisfied
         self
     }
 }
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr
index 12725c3456f..fbf82a24b50 100644
--- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr
@@ -11,6 +11,22 @@ note: required by a bound in `Foo::{synthetic#0}`
 LL |     fn foo<F2>(self) -> impl Foo<T>;
    |                              ^^^^^^ required by this bound in `Foo::{synthetic#0}`
 
+error[E0277]: the trait bound `F2: Foo<u8>` is not satisfied
+  --> $DIR/return-dont-satisfy-bounds.rs:8:34
+   |
+LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+   |                                  ^^^^^^^^^^^^ the trait `Foo<u8>` is not implemented for `F2`
+   |
+note: required by a bound in `<Bar as Foo<char>>::foo`
+  --> $DIR/return-dont-satisfy-bounds.rs:8:16
+   |
+LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+   |                ^^^^^^^ required by this bound in `<Bar as Foo<char>>::foo`
+help: consider further restricting this bound
+   |
+LL |     fn foo<F2: Foo<u8> + Foo<u8>>(self) -> impl Foo<u8> {
+   |                        +++++++++
+
 error[E0276]: impl has stricter requirements than trait
   --> $DIR/return-dont-satisfy-bounds.rs:8:16
    |
@@ -32,7 +48,7 @@ LL |         self
    = help: the trait `Foo<char>` is implemented for `Bar`
    = help: for that trait implementation, expected `char`, found `u8`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0276, E0277.
 For more information about an error, try `rustc --explain E0276`.
diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs
index 85eeb5d4c90..eab436fa341 100644
--- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs
+++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs
@@ -7,6 +7,7 @@ async fn wrapper<F>(f: F)
 //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
 //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
 //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
+//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
 where
 F:,
 for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
index 578ba149baf..e9f97d1d93b 100644
--- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
+++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr
@@ -5,7 +5,7 @@ LL | / async fn wrapper<F>(f: F)
 LL | |
 LL | |
 LL | |
-LL | | where
+...  |
 LL | | F:,
 LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
    | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
@@ -27,7 +27,7 @@ LL | / async fn wrapper<F>(f: F)
 LL | |
 LL | |
 LL | |
-LL | | where
+...  |
 LL | | F:,
 LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
    | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
@@ -35,7 +35,22 @@ LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a
    = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
 
 error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
-  --> $DIR/issue-76168-hr-outlives-3.rs:13:1
+  --> $DIR/issue-76168-hr-outlives-3.rs:6:1
+   |
+LL | / async fn wrapper<F>(f: F)
+LL | |
+LL | |
+LL | |
+...  |
+LL | | F:,
+LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
+   | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
+   |
+   = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
+  --> $DIR/issue-76168-hr-outlives-3.rs:14:1
    |
 LL | / {
 LL | |
@@ -46,6 +61,6 @@ LL | | }
    |
    = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr
index 6c259621466..40e16dde6e4 100644
--- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr
+++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr
@@ -8,6 +8,27 @@ LL | #![feature(non_lifetime_binders)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0309]: the placeholder type `!1_"F"` may not live long enough
+  --> $DIR/type-match-with-late-bound.rs:8:1
+   |
+LL |   async fn walk2<'a, T: 'a>(_: T)
+   |   ^              -- the placeholder type `!1_"F"` must be valid for the lifetime `'a` as defined here...
+   |  _|
+   | |
+LL | | where
+LL | |     for<F> F: 'a,
+   | |_________________^ ...so that the type `F` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/type-match-with-late-bound.rs:10:15
+   |
+LL |     for<F> F: 'a,
+   |               ^^
+help: consider adding an explicit lifetime bound
+   |
+LL |     for<F> F: 'a, !1_"F": 'a
+   |                 ~~~~~~~~~~~~
+
+error[E0309]: the placeholder type `!1_"F"` may not live long enough
   --> $DIR/type-match-with-late-bound.rs:11:1
    |
 LL | async fn walk2<'a, T: 'a>(_: T)
@@ -35,6 +56,6 @@ help: consider adding an explicit lifetime bound
 LL |     for<F> F: 'a, !2_"F": 'a
    |                 ~~~~~~~~~~~~
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0309`.