]> git.lizzy.rs Git - rust.git/commitdiff
modify leak-check to track only outgoing edges from placeholders
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 18 May 2020 09:43:36 +0000 (09:43 +0000)
committerNiko Matsakis <niko@alum.mit.edu>
Mon, 22 Jun 2020 14:05:00 +0000 (14:05 +0000)
Also, update the affected tests. This seems strictly better but it is
actually more permissive than I initially intended. In particular it
accepts this

```
forall<'a, 'b> {
  exists<'intersection> {
    'a: 'intersection,
    'b: 'intersection,
  }
}
```

and I'm not sure I want to accept that. It implies that we have a
`'empty` in the new universe intoduced by the `forall`.

30 files changed:
src/librustc_infer/infer/region_constraints/leak_check.rs
src/test/ui/closure-expected-type/expect-fn-supply-fn.rs
src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr
src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr
src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr
src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr
src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr
src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr
src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr
src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr
src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr
src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr
src/test/ui/hr-subtype/hr-subtype.rs
src/test/ui/hrtb/hrtb-exists-forall-fn.stderr
src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs
src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
src/test/ui/hrtb/hrtb-just-for-static.stderr
src/test/ui/hrtb/issue-46989.rs
src/test/ui/hrtb/issue-46989.stderr
src/test/ui/issues/issue-57362-1.rs
src/test/ui/issues/issue-57362-1.stderr
src/test/ui/issues/issue-57362-2.rs
src/test/ui/issues/issue-57362-2.stderr
src/test/ui/lub-glb/old-lub-glb-hr.rs
src/test/ui/lub-glb/old-lub-glb-hr.stderr
src/test/ui/regions-fn-subtyping-return-static-fail.stderr
src/test/ui/where-clauses/where-for-self-2.rs
src/test/ui/where-clauses/where-for-self-2.stderr

index 91c39a0e78ffb732ef8340a2cc8b4512b6983013..111a7b997a4867eaa8c6a46d12871213bd295940 100644 (file)
@@ -42,10 +42,23 @@ pub fn leak_check(
                 _ => bug!("leak_check: expected placeholder found {:?}", placeholder_region,),
             };
 
-            // Find all regions that are related to this placeholder
-            // in some way. This means any region that either outlives
-            // or is outlived by a placeholder.
-            let mut taint_set = TaintSet::new(TaintDirections::both(), placeholder_region);
+            // Find all regions that this placeholder `!p` must outlive -- i.e.,
+            // any region `r` where `!p: r` must hold. It is an error if any
+            // such region `r` is another placeholder or in a universe that
+            // can't see the placeholder. (This is actually incorrect, because
+            // we don't take into account the possibility of bounds in
+            // environment that tell us that the placeholder may be related to
+            // other regions).
+            //
+            // Note that we *don't* look for cases like `r: !p`. This is
+            // because:
+            //
+            // * If `r` is some other placeholder `!p1`, then we'll find the
+            //   error when we search the regions that `!p1` must outlive.
+            // * If `r` is a variable in some outer universe, then it can
+            //   potentially be assigned to `'static`, so this relation could
+            //   hold.
+            let mut taint_set = TaintSet::new(TaintDirections::outgoing(), placeholder_region);
             taint_set.fixed_point(
                 tcx,
                 self.undo_log.region_constraints(),
index a4e43da91baf8d805275a5913d807202a9014c40..6977fd47a2e85f03ead9066f7d3b6ef41812d651 100644 (file)
@@ -28,14 +28,14 @@ fn expect_free_supply_bound() {
     // Here, we are given a function whose region is bound at closure level,
     // but we expect one bound in the argument. Error results.
     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-    //~^ ERROR type mismatch
+    //~^ ERROR mismatched types
 }
 
 fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
     // Here, we are given a `fn(&u32)` but we expect a `fn(&'x
     // u32)`. In principle, this could be ok, but we demand equality.
     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-    //~^ ERROR type mismatch
+    //~^ ERROR mismatched types
 }
 
 fn expect_bound_supply_free_from_closure() {
@@ -44,7 +44,7 @@ fn expect_bound_supply_free_from_closure() {
     // the argument level.
     type Foo<'a> = fn(&'a u32);
     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-    //~^ ERROR type mismatch
+    //~^ ERROR mismatched types
     });
 }
 
index fae41c4114abc49621895e30b76b73d935008ea4..8a183bb704b4d7220010883ec6bed11131141264 100644 (file)
@@ -36,46 +36,33 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the b
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
    |                                                ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/expect-fn-supply-fn.rs:30:5
+error[E0308]: mismatched types
+  --> $DIR/expect-fn-supply-fn.rs:30:52
    |
-LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
-   |    ------------------------------------------ required by a bound in this
-LL |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
-   |                      ------------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
-...
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
-   |     |
-   |     expected signature of `fn(fn(&'a u32), &i32) -> _`
+   |                                                    ^^^^^^^^ one type is more general than the other
+   |
+   = note: expected fn pointer `fn(&u32)`
+              found fn pointer `for<'r> fn(&'r u32)`
 
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/expect-fn-supply-fn.rs:37:5
+error[E0308]: mismatched types
+  --> $DIR/expect-fn-supply-fn.rs:37:53
    |
-LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-   |    ------------------------------------------- required by a bound in this
-LL |     where F: FnOnce(fn(&u32), &i32)
-   |              ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
-...
 LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
-   |     |
-   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+   |                                                     ^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'r> fn(&'r u32)`
+              found fn pointer `fn(&'x u32)`
 
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/expect-fn-supply-fn.rs:46:5
+error[E0308]: mismatched types
+  --> $DIR/expect-fn-supply-fn.rs:46:53
    |
-LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-   |    ------------------------------------------- required by a bound in this
-LL |     where F: FnOnce(fn(&u32), &i32)
-   |              ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
-...
 LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
-   |     |
-   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+   |                                                     ^^^^^^^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'r> fn(&'r u32)`
+              found fn pointer `fn(&u32)`
 
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0308, E0631.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
index 45f53d4fe99db100ec221ad503ca80717c510b44..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,17 +1,14 @@
-error[E0308]: mismatched types
-  --> $DIR/hr-subtype.rs:39:26
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/hr-subtype.rs:96:1
    |
-LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
-...
-LL | / check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32),
-LL | |                                 for<'a>    fn(&'a u32, &'a u32)) }
-   | |__________________________________________________________________- in this macro invocation
-   |
-   = note: expected enum `std::option::Option<for<'a, 'b> fn(&'a u32, &'b u32)>`
-              found enum `std::option::Option<for<'a> fn(&'a u32, &'a u32)>`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
index 6aba6466fada53b920ef1bcd13d0eaf27a98ebec..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,11 +1,11 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:100:1
+  --> $DIR/hr-subtype.rs:96:1
    |
 LL | / fn main() {
 LL | |
 LL | |
 LL | |
-LL | |
+...  |
 LL | |
 LL | | }
    | |_^
index 6aba6466fada53b920ef1bcd13d0eaf27a98ebec..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,11 +1,11 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:100:1
+  --> $DIR/hr-subtype.rs:96:1
    |
 LL | / fn main() {
 LL | |
 LL | |
 LL | |
-LL | |
+...  |
 LL | |
 LL | | }
    | |_^
index c3e4f6d2ed0c1c91e348822f324bcacb0e28f386..b3e3f5dc401cf22161f590df7d1d3a609cbba560 100644 (file)
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:39:26
    |
 LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
+   |                            ^^^^^^^^^^^ one type is more general than the other
 ...
 LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
 LL | |                              fn(&'x u32)) }
index 4d7b86027f56463d68b380b4bd73d51b354d1f93..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,17 +1,14 @@
-error[E0308]: mismatched types
-  --> $DIR/hr-subtype.rs:39:26
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/hr-subtype.rs:96:1
    |
-LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
-...
-LL | / check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>),
-LL | |                                       for<'a>    fn(Co<'a>, Co<'a>)) }
-   | |______________________________________________________________________- in this macro invocation
-   |
-   = note: expected enum `std::option::Option<for<'a, 'b> fn(Co<'a>, Co<'b>)>`
-              found enum `std::option::Option<for<'a> fn(Co<'a>, Co<'a>)>`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
index 7f0a4197dd7fe412d5602ba145b5a0c8970e48bc..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,17 +1,14 @@
-error[E0308]: mismatched types
-  --> $DIR/hr-subtype.rs:39:26
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/hr-subtype.rs:96:1
    |
-LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
-...
-LL | / check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>,
-LL | |                                         for<'a>    fn(Co<'a>, Co<'a>) -> Contra<'a>) }
-   | |______________________________________________________________________________________- in this macro invocation
-   |
-   = note: expected enum `std::option::Option<for<'a, 'b> fn(Co<'a>, Co<'b>) -> Contra<'a>>`
-              found enum `std::option::Option<for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>>`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
index 6aba6466fada53b920ef1bcd13d0eaf27a98ebec..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,11 +1,11 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:100:1
+  --> $DIR/hr-subtype.rs:96:1
    |
 LL | / fn main() {
 LL | |
 LL | |
 LL | |
-LL | |
+...  |
 LL | |
 LL | | }
    | |_^
index c12e543a44e79e29a8cd21449e220cbfd0a96864..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,17 +1,14 @@
-error[E0308]: mismatched types
-  --> $DIR/hr-subtype.rs:39:26
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/hr-subtype.rs:96:1
    |
-LL |               gimme::<$t1>(None::<$t2>);
-   |                            ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a
-...
-LL | / check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>,
-LL | |                                             for<'a>    fn(Contra<'a>, Contra<'a>) -> Co<'a>) }
-   | |______________________________________________________________________________________________- in this macro invocation
-   |
-   = note: expected enum `std::option::Option<for<'a, 'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>>`
-              found enum `std::option::Option<for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>>`
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
index 6aba6466fada53b920ef1bcd13d0eaf27a98ebec..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,11 +1,11 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:100:1
+  --> $DIR/hr-subtype.rs:96:1
    |
 LL | / fn main() {
 LL | |
 LL | |
 LL | |
-LL | |
+...  |
 LL | |
 LL | | }
    | |_^
index 6aba6466fada53b920ef1bcd13d0eaf27a98ebec..c4e838e6887b58f2dd1f40747181aef27761638a 100644 (file)
@@ -1,11 +1,11 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:100:1
+  --> $DIR/hr-subtype.rs:96:1
    |
 LL | / fn main() {
 LL | |
 LL | |
 LL | |
-LL | |
+...  |
 LL | |
 LL | | }
    | |_^
index b31f198bd97bf8cee87182f5f2efae6780ce8870..995ec64d53b83b6ad6b67ec891e2663972316e63 100644 (file)
@@ -42,10 +42,6 @@ fn supertype<'x,'y:'x,'z:'y>() {
             //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR
             //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR
             //[free_inv_x_vs_free_inv_y]~^^^^^ ERROR
-            //[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types
-            //[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR
-            //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR
-            //[bound_co_a_b_vs_bound_co_a]~^^^^^^^^^ ERROR
         }
     }
 }
@@ -103,4 +99,8 @@ fn main() {
 //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR fatal error triggered by #[rustc_error]
 //[bound_co_a_vs_bound_co_b]~^^^^ ERROR fatal error triggered by #[rustc_error]
 //[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
+//[bound_a_b_vs_bound_a]~^^^^^^ ERROR fatal error triggered by #[rustc_error]
+//[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR fatal error triggered by #[rustc_error]
+//[bound_co_a_co_b_ret_contra_a]~^^^^^^^^ ERROR fatal error triggered by #[rustc_error]
+//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR fatal error triggered by #[rustc_error]
 }
index 328e98657effb179aa1f90cc61ec76274c533b00..9914783d9767d5d99ecd0790eae8597cc1714265 100644 (file)
@@ -2,9 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/hrtb-exists-forall-fn.rs:17:34
    |
 LL |     let _: for<'b> fn(&'b u32) = foo();
-   |            -------------------   ^^^^^ expected concrete lifetime, found bound lifetime parameter 'b
-   |            |
-   |            expected due to this
+   |                                  ^^^^^ one type is more general than the other
    |
    = note: expected fn pointer `for<'b> fn(&'b u32)`
               found fn pointer `fn(&u32)`
index 4c1d4d28a09b01eace9d5efbd5a2596ea8632f14..921061916fc95b7d46c891db83d39cfae29499a5 100644 (file)
@@ -32,5 +32,5 @@ fn main() {
     // NB. *However*, the reinstated leak-check gives an error here.
 
     foo::<()>();
-    //~^ ERROR not satisfied
+    //~^ ERROR implementation of `Trait` is not general enough
 }
index 7a7285d3d76e051dbc23c8ee082448a4be4fe33e..fe8209d054c8ad641044ddda3eda030241b2ec80 100644 (file)
@@ -1,18 +1,14 @@
-error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied
-  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:11
+error: implementation of `Trait` is not general enough
+  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
    |
-LL | fn foo<T>()
-   |    --- required by a bound in this
-LL | where
-LL |     T: Trait<for<'b> fn(&'b u32)>,
-   |        -------------------------- required by this bound in `foo`
+LL | trait Trait<T> {}
+   | ----------------- trait `Trait` defined here
 ...
 LL |     foo::<()>();
-   |           ^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
+   |     ^^^^^^^^^ implementation of `Trait` is not general enough
    |
-   = help: the following implementations were found:
-             <() as Trait<fn(&'a u32)>>
+   = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
+   = note: ...but `()` actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
index 87a13889298dfc81f40b9d9cc3923b50942cabc0..ebb3abf184856de4a69b9fe9eceeed0f22da89f1 100644 (file)
@@ -1,19 +1,12 @@
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
+error[E0308]: mismatched types
+  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
    |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this
-LL |     where B : for<'ccx> Bar<'ccx>
-   |               ------------------- required by this bound in `want_bar_for_any_ccx`
-...
 LL |     want_bar_for_any_ccx(b);
-   |                          ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |     ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
-help: consider further restricting this bound
-   |
-LL |     where B : Qux + for<'ccx> Bar<'ccx>
-   |                   ^^^^^^^^^^^^^^^^^^^^^
+   = note: expected type `for<'ccx> Bar<'ccx>`
+              found type `Bar<'static>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0308`.
index 4fa404624775b731bba309d7034687fefba4fd1d..bf7373059a074485da4a23bdf776783768c493bc 100644 (file)
@@ -1,16 +1,16 @@
-error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied
-  --> $DIR/hrtb-just-for-static.rs:24:17
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-just-for-static.rs:24:5
    |
-LL | fn want_hrtb<T>()
-   |    --------- required by a bound in this
-LL |     where T : for<'a> Foo<&'a isize>
-   |               ---------------------- required by this bound in `want_hrtb`
+LL | / trait Foo<X> {
+LL | |     fn foo(&self, x: X) { }
+LL | | }
+   | |_- trait `Foo` defined here
 ...
-LL |     want_hrtb::<StaticInt>()
-   |                 ^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
+LL |       want_hrtb::<StaticInt>()
+   |       ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = help: the following implementations were found:
-             <StaticInt as Foo<&'static isize>>
+   = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
+   = note: ...but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1`
 
 error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied
   --> $DIR/hrtb-just-for-static.rs:30:17
index 2c8590554580719201b873c12e6a9afdbeb89d39..eb6549099fe6a85b303af4529e473833abba5993 100644 (file)
@@ -38,5 +38,5 @@ fn assert_foo<T: Foo>() {}
 
 fn main() {
     assert_foo::<fn(&i32)>();
-    //~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
+    //~^ ERROR implementation of `Foo` is not general enough
 }
index 0a7382c4dd818305ed5794882f83123b7d8ccbe6..0865aa4224b9731c805a3684be62b100749e370a 100644 (file)
@@ -1,15 +1,16 @@
-error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
-  --> $DIR/issue-46989.rs:40:18
+error: implementation of `Foo` is not general enough
+  --> $DIR/issue-46989.rs:40:5
    |
-LL | fn assert_foo<T: Foo>() {}
-   |                  --- required by this bound in `assert_foo`
+LL | / trait Foo {
+LL | |
+LL | | }
+   | |_- trait `Foo` defined here
 ...
-LL |     assert_foo::<fn(&i32)>();
-   |                  ^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)`
+LL |       assert_foo::<fn(&i32)>();
+   |       ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = help: the following implementations were found:
-             <fn(A) as Foo>
+   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
+   = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
index 1fa417fe98ab77b944604f5123b2e9e64049371a..3ba82300fabea9f6282d152dc0b49a54ebb355f9 100644 (file)
@@ -17,7 +17,7 @@ fn f(self) {
 
 fn f() {
     let a: fn(_) = |_: &u8| {};
-    a.f(); //~ ERROR no method named `f`
+    a.f(); //~ ERROR implementation of `Trait` is not general enough
 }
 
 fn main() {}
index 5c611cd43d3ccdf77c39e938c62ecceb778492e8..24408420b1373d122c88061f1ada2ab5c26960d7 100644 (file)
@@ -1,17 +1,16 @@
-error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current scope
+error: implementation of `Trait` is not general enough
   --> $DIR/issue-57362-1.rs:20:7
    |
-LL |     a.f();
-   |       ^ method not found in `fn(&u8)`
+LL | / trait Trait {
+LL | |     fn f(self);
+LL | | }
+   | |_- trait `Trait` defined here
+...
+LL |       a.f();
+   |         ^ implementation of `Trait` is not general enough
    |
-   = note: `a` is a function, perhaps you wish to call it
-   = help: items from traits can only be used if the trait is implemented and in scope
-note: `Trait` defines an item `f`, perhaps you need to implement it
-  --> $DIR/issue-57362-1.rs:8:1
-   |
-LL | trait Trait {
-   | ^^^^^^^^^^^
+   = note: `Trait` would have to be implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`...
+   = note: ...but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0599`.
index 870d7f28ba95302e5d5deb9e248873935a1ad089..7b6594abc96472e5f6b1f727b886bd7bcf326aaa 100644 (file)
@@ -19,7 +19,9 @@ fn make_g() -> Self::G {
 }
 
 fn g() {
-    let x = <fn (&())>::make_g(); //~ ERROR no function or associated item
+    let x = <fn (&())>::make_g();
+    //~^ ERROR implementation of `X` is not general enough
+    //~| ERROR implementation of `X` is not general enough
 }
 
 fn main() {}
index 2edc00974645530ad741960f43c8b1d3f3a5e6ec..dfd48ec22275b440f111986305e96a4b2ba0ddce 100644 (file)
@@ -1,16 +1,33 @@
-error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'r> fn(&'r ())` in the current scope
-  --> $DIR/issue-57362-2.rs:22:25
+error: implementation of `X` is not general enough
+  --> $DIR/issue-57362-2.rs:22:13
    |
-LL |     let x = <fn (&())>::make_g();
-   |                         ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())`
+LL | / trait X {
+LL | |     type G;
+LL | |     fn make_g() -> Self::G;
+LL | | }
+   | |_- trait `X` defined here
+...
+LL |       let x = <fn (&())>::make_g();
+   |               ^^^^^^^^^^^^^^^^^^ implementation of `X` is not general enough
    |
-   = help: items from traits can only be used if the trait is implemented and in scope
-note: `X` defines an item `make_g`, perhaps you need to implement it
-  --> $DIR/issue-57362-2.rs:8:1
+   = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())`
+   = note: ...but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
+
+error: implementation of `X` is not general enough
+  --> $DIR/issue-57362-2.rs:22:13
+   |
+LL | / trait X {
+LL | |     type G;
+LL | |     fn make_g() -> Self::G;
+   | |     ----------------------- due to a where-clause on `X::make_g`...
+LL | | }
+   | |_- trait `X` defined here
+...
+LL |       let x = <fn (&())>::make_g();
+   |               ^^^^^^^^^^^^^^^^^^ doesn't satisfy where-clause
    |
-LL | trait X {
-   | ^^^^^^^
+   = note: ...`X` would have to be implemented for the type `for<'r> fn(&'r ())`
+   = note: ...but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0599`.
index bc7b787cd65ac3bff77e4b354bd08839731e2f3b..5e24a99bcc3311503721d0ec05cc7133d060c0d1 100644 (file)
@@ -3,21 +3,21 @@
 // error. However, now that we handle subtyping correctly, we no
 // longer get an error, because we recognize these two types as
 // equivalent!
-//
-// Whoops -- now that we reinstituted the leak-check, we get an error
-// again.
 
 fn foo(
     x: fn(&u8, &u8),
     y: for<'a> fn(&'a u8, &'a u8),
 ) {
+    // The two types above are actually equivalent. With the older
+    // leak check, though, we didn't consider them as equivalent, and
+    // hence we gave errors. But now we've fixed that.
     let z = match 22 {
         0 => x,
-        _ => y, //~ ERROR `match` arms have incompatible types
+        _ => y,
     };
 }
 
-fn bar(
+fn foo_cast(
     x: fn(&u8, &u8),
     y: for<'a> fn(&'a u8, &'a u8),
 ) {
@@ -28,5 +28,30 @@ fn bar(
     };
 }
 
+fn bar(
+    x: for<'a, 'b> fn(&'a u8, &'b u8)-> &'a u8,
+    y: for<'a> fn(&'a u8, &'a u8) -> &'a u8,
+) {
+    // The two types above are not equivalent. With the older LUB/GLB
+    // algorithm, this may have worked (I don't remember), but now it
+    // doesn't because we require equality.
+    let z = match 22 {
+        0 => x,
+        _ => y, //~ ERROR `match` arms have incompatible types
+    };
+}
+
+fn bar_cast(
+    x: for<'a, 'b> fn(&'a u8, &'b u8)-> &'a u8,
+    y: for<'a> fn(&'a u8, &'a u8) -> &'a u8,
+) {
+    // But we can *upcast* explicitly the type of `x` and figure
+    // things out:
+    let z = match 22 {
+        0 => x as for<'a> fn(&'a u8, &'a u8) -> &'a u8,
+        _ => y,
+    };
+}
+
 fn main() {
 }
index 6d5d51174699fa17569e33b837610acf441487f0..d242fb7789aa1e76635ef7d26861077e647568b2 100644 (file)
@@ -1,17 +1,17 @@
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/old-lub-glb-hr.rs:16:14
+  --> $DIR/old-lub-glb-hr.rs:40:14
    |
 LL |       let z = match 22 {
    |  _____________-
 LL | |         0 => x,
-   | |              - this is found to be of type `for<'r, 's> fn(&'r u8, &'s u8)`
+   | |              - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
 LL | |         _ => y,
-   | |              ^ expected bound lifetime parameter, found concrete lifetime
+   | |              ^ expected bound lifetime parameter 'a, found concrete lifetime
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
-   = note:    expected type `for<'r, 's> fn(&'r u8, &'s u8)`
-           found fn pointer `for<'a> fn(&'a u8, &'a u8)`
+   = note:    expected type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
+           found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8`
 
 error: aborting due to previous error
 
index 27704b3e0a8c7421414764b1fb62e28d74f11b33..7848f770a70cf0b56f23e1730a4e121e47a5a3b4 100644 (file)
@@ -11,10 +11,10 @@ error[E0308]: mismatched types
   --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12
    |
 LL |     want_G(baz);
-   |            ^^^ expected concrete lifetime, found bound lifetime parameter 'cx
+   |            ^^^ one type is more general than the other
    |
    = note: expected fn pointer `for<'cx> fn(&'cx S) -> &'static S`
-                 found fn item `for<'r> fn(&'r S) -> &'r S {baz}`
+              found fn pointer `for<'r> fn(&'r S) -> &'r S`
 
 error: aborting due to 2 previous errors
 
index 31174fd4cf16373b5201e1d91f785350d42bff34..0ce38e69f6b0fa8c29c4a45f5305713e7e6f7d15 100644 (file)
@@ -18,5 +18,5 @@ fn foo<T>(x: &T)
 {}
 
 fn main() {
-    foo(&X); //~ ERROR trait bound
+    foo(&X); //~ ERROR implementation of `Bar` is not general enough
 }
index 9976243b200dc907562306b21bee2ef8995e799e..b3cadf5b1b078859b0b251a3f63d9046ec1b5505 100644 (file)
@@ -1,17 +1,16 @@
-error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied
+error: implementation of `Bar` is not general enough
   --> $DIR/where-for-self-2.rs:21:5
    |
-LL | fn foo<T>(x: &T)
-   |    --- required by a bound in this
-LL |     where for<'a> &'a T: Bar
-   |                          --- required by this bound in `foo`
+LL | / trait Bar {
+LL | |     fn bar(&self);
+LL | | }
+   | |_- trait `Bar` defined here
 ...
-LL |     foo(&X);
-   |     ^^^ the trait `for<'a> Bar` is not implemented for `&'a _`
+LL |       foo(&X);
+   |       ^^^ implementation of `Bar` is not general enough
    |
-   = help: the following implementations were found:
-             <&'static u32 as Bar>
+   = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
+   = note: ...but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.