]> git.lizzy.rs Git - rust.git/commitdiff
move leak-check to during coherence, candidate eval
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 20 May 2020 10:19:36 +0000 (10:19 +0000)
committerNiko Matsakis <niko@alum.mit.edu>
Mon, 22 Jun 2020 15:33:05 +0000 (15:33 +0000)
In particular, it no longer occurs during the subtyping check. This is
important for enabling lazy normalization, because the subtyping check
will be producing sub-obligations that could affect its results.

Consider an example like

    for<'a> fn(<&'a as Mirror>::Item) =
      fn(&'b u8)

where `<T as Mirror>::Item = T` for all `T`. We will wish to produce a
new subobligation like

    <'!1 as Mirror>::Item = &'b u8

This will, after being solved, ultimately yield a constraint that `'!1
= 'b` which will fail. But with the leak-check being performed on
subtyping, there is no opportunity to normalize `<'!1 as
Mirror>::Item` (unless we invoke that normalization directly from
within subtyping, and I would prefer that subtyping and unification
are distinct operations rather than part of the trait solving stack).

The reason to keep the leak check during coherence and trait
evaluation is partly for backwards compatibility. The coherence change
permits impls for `fn(T)` and `fn(&T)` to co-exist, and the trait
evaluation change means that we can distinguish those two cases
without ambiguity errors. It also avoids recreating #57639, where we
were incorrectly choosing a where clause that would have failed the
leak check over the impl which succeeds.

The other reason to keep the leak check in those places is that I
think it is actually close to the model we want. To the point, I think
the trait solver ought to have the job of "breaking down"
higher-ranked region obligation like ``!1: '2` into into region
obligations that operate on things in the root universe, at which
point they should be handed off to polonius. The leak check isn't
*really* doing that -- these obligations are still handed to the
region solver to process -- but if/when we do adopt that model, the
decision to pass/fail would be happening in roughly this part of the
code.

This change had somewhat more side-effects than I anticipated. It
seems like there are cases where the leak-check was not being enforced
during method proving and trait selection. I haven't quite tracked
this down but I think it ought to be documented, so that we know what
precisely we are committing to.

One surprising test was `issue-30786.rs`. The behavior there seems a
bit "fishy" to me, but the problem is not related to the leak check
change as far as I can tell, but more to do with the closure signature
inference code and perhaps the associated type projection, which
together seem to be conspiring to produce an unexpected
signature. Nonetheless, it is an example of where changing the
leak-check can have some unexpected consequences: we're now failing to
resolve a method earlier than we were, which suggests we might change
some method resolutions that would have been ambiguous to be
successful.

TODO:

* figure out remainig test failures
* add new coherence tests for the patterns we ARE disallowing

60 files changed:
src/librustc_infer/infer/higher_ranked/mod.rs
src/librustc_infer/infer/region_constraints/leak_check.rs
src/librustc_trait_selection/traits/coherence.rs
src/librustc_trait_selection/traits/project.rs
src/librustc_trait_selection/traits/select/mod.rs
src/test/ui/associated-types/associated-types-eq-hr.stderr
src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr
src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
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/closures/issue-41366.rs
src/test/ui/closures/issue-41366.stderr
src/test/ui/generator/resume-arg-late-bound.rs
src/test/ui/generator/resume-arg-late-bound.stderr
src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.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_b_vs_bound_inv_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/issue-30786.migrate.stderr
src/test/ui/hrtb/issue-30786.nll.stderr
src/test/ui/hrtb/issue-30786.rs
src/test/ui/issues/issue-40000.stderr
src/test/ui/issues/issue-43623.rs
src/test/ui/issues/issue-43623.stderr
src/test/ui/issues/issue-60283.rs
src/test/ui/issues/issue-60283.stderr
src/test/ui/lub-glb/old-lub-glb-hr.rs
src/test/ui/lub-glb/old-lub-glb-hr.stderr
src/test/ui/lub-glb/old-lub-glb-object.stderr
src/test/ui/mismatched_types/closure-arg-type-mismatch.rs
src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
src/test/ui/mismatched_types/closure-mismatch.rs
src/test/ui/mismatched_types/closure-mismatch.stderr
src/test/ui/regions-fn-subtyping-return-static-fail.stderr
src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr
src/test/ui/rfc1623.rs
src/test/ui/rfc1623.stderr
src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs
src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs
src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs
src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr

index b94221785ae755b4a15dd4d32239dab74b0207df..b6251e34008a36fe922e63b9cc4dd87cd9280857 100644 (file)
@@ -30,7 +30,7 @@ pub fn higher_ranked_sub<T>(
 
         let span = self.trace.cause.span;
 
-        self.infcx.commit_if_ok(|snapshot| {
+        self.infcx.commit_if_ok(|_| {
             // First, we instantiate each bound region in the supertype with a
             // fresh placeholder region.
             let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b);
@@ -48,8 +48,6 @@ pub fn higher_ranked_sub<T>(
             // Compare types now that bound regions have been replaced.
             let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?;
 
-            self.infcx.leak_check(!a_is_expected, snapshot)?;
-
             debug!("higher_ranked_sub: OK result={:?}", result);
 
             Ok(ty::Binder::bind(result))
@@ -75,7 +73,12 @@ pub fn replace_bound_vars_with_placeholders<T>(
     where
         T: TypeFoldable<'tcx>,
     {
-        let next_universe = self.create_next_universe();
+        // Figure out what the next universe will be, but don't actually create
+        // it until after we've done the substitution (in particular there may
+        // be no bound variables). This is a performance optimization, since the
+        // leak check for example can be skipped if no new universes are created
+        // (i.e., if there are no placeholders).
+        let next_universe = self.universe().next_universe();
 
         let fld_r = |br| {
             self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
@@ -103,6 +106,13 @@ pub fn replace_bound_vars_with_placeholders<T>(
 
         let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c);
 
+        // If there were higher-ranked regions to replace, then actually create
+        // the next universe (this avoids needlessly creating universes).
+        if !map.is_empty() {
+            let n_u = self.create_next_universe();
+            assert_eq!(n_u, next_universe);
+        }
+
         debug!(
             "replace_bound_vars_with_placeholders(\
              next_universe={:?}, \
index f3b78909b42d890328127eadb47c3df349145365..32e708bf52b32fc2568ab8ad3f83e94a314a4878 100644 (file)
@@ -286,6 +286,7 @@ fn error(
         placeholder: ty::PlaceholderRegion,
         other_region: ty::Region<'tcx>,
     ) -> TypeError<'tcx> {
+        debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region);
         if self.overly_polymorphic {
             return TypeError::RegionsOverlyPolymorphic(placeholder.name, other_region);
         } else {
index 706cbf058b713b354ce7d985d4bba9772790c044..3ec7fe2bf25c68f2635fb64f117a8487ee374bde 100644 (file)
@@ -120,12 +120,13 @@ fn overlap<'cx, 'tcx>(
     debug!("overlap(a_def_id={:?}, b_def_id={:?})", a_def_id, b_def_id);
 
     selcx.infcx().probe_maybe_skip_leak_check(skip_leak_check.is_yes(), |snapshot| {
-        overlap_within_probe(selcx, a_def_id, b_def_id, snapshot)
+        overlap_within_probe(selcx, skip_leak_check, a_def_id, b_def_id, snapshot)
     })
 }
 
 fn overlap_within_probe(
     selcx: &mut SelectionContext<'cx, 'tcx>,
+    skip_leak_check: SkipLeakCheck,
     a_def_id: DefId,
     b_def_id: DefId,
     snapshot: &CombinedSnapshot<'_, 'tcx>,
@@ -180,6 +181,13 @@ fn overlap_within_probe(
         return None;
     }
 
+    if !skip_leak_check.is_yes() {
+        if let Err(_) = infcx.leak_check(true, snapshot) {
+            debug!("overlap: leak check failed");
+            return None;
+        }
+    }
+
     let impl_header = selcx.infcx().resolve_vars_if_possible(&a_impl_header);
     let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
     debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
index 4bc58fbaadcda8b516fd265b3f7f9655281d04c8..ae255c22f9dcaf09f054c5af045c53de4e83ed9e 100644 (file)
@@ -298,11 +298,7 @@ fn new(
     fn fold<T: TypeFoldable<'tcx>>(&mut self, value: &T) -> T {
         let value = self.selcx.infcx().resolve_vars_if_possible(value);
 
-        if !value.has_projections() {
-            value
-        } else {
-            value.fold_with(self)
-        }
+        if !value.has_projections() { value } else { value.fold_with(self) }
     }
 }
 
index e90acbbce67ba17643d3674309e03ff7463f6a12..e5960e731033f0f0852ad09d42c618c975a64157 100644 (file)
@@ -347,6 +347,12 @@ fn evaluation_probe(
     ) -> Result<EvaluationResult, OverflowError> {
         self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
             let result = op(self)?;
+
+            match self.infcx.leak_check(true, snapshot) {
+                Ok(()) => {}
+                Err(_) => return Ok(EvaluatedToErr),
+            }
+
             match self.infcx.region_constraints_added_in_snapshot(snapshot) {
                 None => Ok(result),
                 Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
@@ -2402,11 +2408,7 @@ fn head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
     }
 
     fn depth(&self) -> usize {
-        if let Some(head) = self.head {
-            head.depth
-        } else {
-            0
-        }
+        if let Some(head) = self.head { head.depth } else { 0 }
     }
 }
 
index 50f1d07142f8c8ee18f43bd8411c0be3e326acba..315d180844d7adf4d1abb07a3810c04de998eec9 100644 (file)
@@ -74,7 +74,7 @@ LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
    |                                                           ------------- required by this bound in `tuple_two`
 ...
 LL |     tuple_two::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
+   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:107:18
index 5009e0868a7d4f8a8cf673ce3c219c5b87b35e9d..9462121bdf203d44c984ba4b13158a9a3869ca9c 100644 (file)
@@ -1,23 +1,23 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/project-fn-ret-invariant.rs:53:21
+  --> $DIR/project-fn-ret-invariant.rs:54:22
    |
-LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-   |                                     --------     --------------------
-   |                                     |
-   |                                     this parameter and the return type are declared with different lifetimes...
-LL |    let a = bar(foo, y);
-   |                     ^ ...but data from `x` is returned here
+LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+   |                                      --------     --------------------
+   |                                      |
+   |                                      this parameter and the return type are declared with different lifetimes...
+LL |     let a = bar(foo, y);
+   |                      ^ ...but data from `x` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/project-fn-ret-invariant.rs:54:21
+  --> $DIR/project-fn-ret-invariant.rs:56:9
    |
-LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-   |                        --------                  --------------------
-   |                        |
-   |                        this parameter and the return type are declared with different lifetimes...
-LL |    let a = bar(foo, y);
-LL |    let b = bar(foo, x);
-   |                     ^ ...but data from `y` is returned here
+LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+   |                                      --------     --------------------
+   |                                      |
+   |                                      this parameter and the return type are declared with different lifetimes...
+...
+LL |     (a, b)
+   |         ^ ...but data from `x` is returned here
 
 error: aborting due to 2 previous errors
 
index 8f445acf2b98cf4fae8b7327221c731c98ecda97..2156ecb17393f2e96bb850086d7ea8552665cb66 100644 (file)
@@ -1,8 +1,8 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/project-fn-ret-invariant.rs:59:1
+  --> $DIR/project-fn-ret-invariant.rs:60:1
    |
-LL | fn main() { }
-   | ^^^^^^^^^^^^^
+LL | fn main() {}
+   | ^^^^^^^^^^^^
 
 error: aborting due to previous error
 
index 65d16440ac9b04bb8fd324679ef5314c847b8f82..64b5722390858600908dc9444c69a6953c0d3af2 100644 (file)
@@ -1,13 +1,13 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/project-fn-ret-invariant.rs:39:19
+  --> $DIR/project-fn-ret-invariant.rs:40:20
    |
-LL | fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-   |                               --------     --------------------
-   |                               |
-   |                               this parameter and the return type are declared with different lifetimes...
+LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+   |                                --------     --------------------
+   |                                |
+   |                                this parameter and the return type are declared with different lifetimes...
 ...
-LL |    let b = bar(f, y);
-   |                   ^ ...but data from `x` is returned here
+LL |     let b = bar(f, y);
+   |                    ^ ...but data from `x` is returned here
 
 error: aborting due to previous error
 
index 23d873212ed1edbe7741fd67a35e0b1662d13e50..0034d796826de662b16e8aec226e8e3bfcaf8ada 100644 (file)
@@ -1,60 +1,61 @@
 #![feature(unboxed_closures)]
 #![feature(rustc_attrs)]
-
 // Test for projection cache. We should be able to project distinct
 // lifetimes from `foo` as we reinstantiate it multiple times, but not
 // if we do it just once. In this variant, the region `'a` is used in
 // an invariant position, which affects the results.
 
 // revisions: ok oneuse transmute krisskross
-
 #![allow(dead_code, unused_variables)]
 
 use std::marker::PhantomData;
 
 struct Type<'a> {
     // Invariant
-    data: PhantomData<fn(&'a u32) -> &'a u32>
+    data: PhantomData<fn(&'a u32) -> &'a u32>,
 }
 
-fn foo<'a>() -> Type<'a> { loop { } }
+fn foo<'a>() -> Type<'a> {
+    loop {}
+}
 
 fn bar<T>(t: T, x: T::Output) -> T::Output
-    where T: FnOnce<()>
+where
+    T: FnOnce<()>,
 {
     t()
 }
 
 #[cfg(ok)] // two instantiations: OK
-fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
     let a = bar(foo, x);
     let b = bar(foo, y);
     (a, b)
 }
 
 #[cfg(oneuse)] // one instantiation: BAD
-fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-   let f = foo; // <-- No consistent type can be inferred for `f` here.
-   let a = bar(f, x);
-   let b = bar(f, y); //[oneuse]~ ERROR lifetime mismatch [E0623]
-   (a, b)
+fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+    let f = foo; // <-- No consistent type can be inferred for `f` here.
+    let a = bar(f, x);
+    let b = bar(f, y); //[oneuse]~ ERROR lifetime mismatch [E0623]
+    (a, b)
 }
 
 #[cfg(transmute)] // one instantiations: BAD
-fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
-   // Cannot instantiate `foo` with any lifetime other than `'a`,
-   // since it is provided as input.
+fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
+    // Cannot instantiate `foo` with any lifetime other than `'a`,
+    // since it is provided as input.
 
-   bar(foo, x) //[transmute]~ ERROR E0495
+    bar(foo, x) //[transmute]~ ERROR E0495
 }
 
 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
-fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-   let a = bar(foo, y); //[krisskross]~ ERROR E0623
-   let b = bar(foo, x); //[krisskross]~ ERROR E0623
-   (a, b)
+fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+    let a = bar(foo, y); //[krisskross]~ ERROR E0623
+    let b = bar(foo, x);
+    (a, b) //[krisskross]~ ERROR E0623
 }
 
 #[rustc_error]
-fn main() { }
+fn main() {}
 //[ok]~^ ERROR fatal error triggered by #[rustc_error]
index 0a05fc6bb82863f5bdaf43c410f92cc3d054ee34..ef57f9e0bc480049ba6ed9bfab821693693f1e1f 100644 (file)
@@ -1,27 +1,27 @@
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/project-fn-ret-invariant.rs:48:4
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+  --> $DIR/project-fn-ret-invariant.rs:49:9
    |
-LL |    bar(foo, x)
-   |    ^^^^^^^^^^^
+LL |     bar(foo, x)
+   |         ^^^
    |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8...
-  --> $DIR/project-fn-ret-invariant.rs:44:8
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 45:8...
+  --> $DIR/project-fn-ret-invariant.rs:45:8
    |
-LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
+LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
    |        ^^
 note: ...so that the expression is assignable
-  --> $DIR/project-fn-ret-invariant.rs:48:13
+  --> $DIR/project-fn-ret-invariant.rs:49:14
    |
-LL |    bar(foo, x)
-   |             ^
+LL |     bar(foo, x)
+   |              ^
    = note: expected `Type<'_>`
               found `Type<'a>`
    = note: but, the lifetime must be valid for the static lifetime...
 note: ...so that the expression is assignable
-  --> $DIR/project-fn-ret-invariant.rs:48:4
+  --> $DIR/project-fn-ret-invariant.rs:49:5
    |
-LL |    bar(foo, x)
-   |    ^^^^^^^^^^^
+LL |     bar(foo, x)
+   |     ^^^^^^^^^^^
    = note: expected `Type<'static>`
               found `Type<'_>`
 
index a4e43da91baf8d805275a5913d807202a9014c40..c81c40c18b45b2f4f8ac9322a50a55536de567a8 100644 (file)
@@ -1,10 +1,12 @@
 fn with_closure_expecting_fn_with_free_region<F>(_: F)
-    where F: for<'a> FnOnce(fn(&'a u32), &i32)
+where
+    F: for<'a> FnOnce(fn(&'a u32), &i32),
 {
 }
 
 fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-    where F: FnOnce(fn(&u32), &i32)
+where
+    F: FnOnce(fn(&u32), &i32),
 {
 }
 
@@ -28,14 +30,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 +46,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
     });
 }
 
@@ -52,8 +54,7 @@ fn expect_bound_supply_bound<'x>(x: &'x u32) {
     // No error in this case. The supplied type supplies the bound
     // regions, and hence we are able to figure out the type of `y`
     // from the expected type
-    with_closure_expecting_fn_with_bound_region(|x: for<'z> fn(&'z u32), y| {
-    });
+    with_closure_expecting_fn_with_bound_region(|x: for<'z> fn(&'z u32), y| {});
 }
 
-fn main() { }
+fn main() {}
index fae41c4114abc49621895e30b76b73d935008ea4..0de15dfa7357d349a99dcc340cc9db6c8548e1e4 100644 (file)
@@ -1,81 +1,68 @@
 error[E0308]: mismatched types
-  --> $DIR/expect-fn-supply-fn.rs:14:52
+  --> $DIR/expect-fn-supply-fn.rs:16:52
    |
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
    |                                                    ^^^^^^^^^^^ lifetime mismatch
    |
    = note: expected fn pointer `fn(&u32)`
               found fn pointer `fn(&'x u32)`
-note: the anonymous lifetime #2 defined on the body at 14:48...
-  --> $DIR/expect-fn-supply-fn.rs:14:48
+note: the anonymous lifetime #2 defined on the body at 16:48...
+  --> $DIR/expect-fn-supply-fn.rs:16:48
    |
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
    |                                                ^^^^^^^^^^^^^^^^^^^^^^
-note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 11:36
-  --> $DIR/expect-fn-supply-fn.rs:11:36
+note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 13:36
+  --> $DIR/expect-fn-supply-fn.rs:13:36
    |
 LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
    |                                    ^^
 
 error[E0308]: mismatched types
-  --> $DIR/expect-fn-supply-fn.rs:14:52
+  --> $DIR/expect-fn-supply-fn.rs:16:52
    |
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
    |                                                    ^^^^^^^^^^^ lifetime mismatch
    |
    = note: expected fn pointer `fn(&u32)`
               found fn pointer `fn(&'x u32)`
-note: the lifetime `'x` as defined on the function body at 11:36...
-  --> $DIR/expect-fn-supply-fn.rs:11:36
+note: the lifetime `'x` as defined on the function body at 13:36...
+  --> $DIR/expect-fn-supply-fn.rs:13:36
    |
 LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
    |                                    ^^
-note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 14:48
-  --> $DIR/expect-fn-supply-fn.rs:14:48
+note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 16:48
+  --> $DIR/expect-fn-supply-fn.rs:16:48
    |
 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:32: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:39: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:48: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 5cae0e76d1acbcfa263754ace0d2fc65729b411e..af1e37ba867dee0327622dc1aec9f4c891e7d462 100644 (file)
@@ -7,7 +7,6 @@ impl<'g> T<'g> for u32 {
 }
 
 fn main() {
-    (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
+    (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
     //~^ ERROR: type mismatch in closure arguments
-    //~| ERROR: type mismatch resolving
 }
index 2f2871e9f0e90c89e1cfe7a6cbad4d9e544b278f..9c4b7d529ef4dff52555b5edd6b045cda1ae6f00 100644 (file)
@@ -1,23 +1,14 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/issue-41366.rs:10:5
    |
-LL |     (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
-   |     ^^-----^
+LL |     (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
+   |     ^^------^
    |     | |
-   |     | found signature of `fn(_) -> _`
-   |     expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _`
+   |     | found signature of `fn(u16) -> _`
+   |     expected signature of `fn(<u32 as T<'x>>::V) -> _`
    |
    = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(<u32 as T<'x>>::V)`
 
-error[E0271]: type mismatch resolving `for<'x> <[closure@$DIR/issue-41366.rs:10:7: 10:12] as std::ops::FnOnce<(<u32 as T<'x>>::V,)>>::Output == ()`
-  --> $DIR/issue-41366.rs:10:5
-   |
-LL |     (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
-   |     ^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
-   |
-   = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(<u32 as T<'x>>::V)`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0271, E0631.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0631`.
index 87b1f1a065bc8c3099b34410267256398fb84765..a8f657eaabe47b8ba69ffeaea6f4cb5b70becdcd 100644 (file)
@@ -13,5 +13,6 @@ fn main() {
         *arg = true;
     };
     test(gen);
-    //~^ ERROR type mismatch in function arguments
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
 }
index ffa440daed8c45088be819f24f8e4bb8e9a12c60..c379d9eae8ecdc375dba5d70bd3e247eb0b7140a 100644 (file)
@@ -1,15 +1,21 @@
-error[E0631]: type mismatch in function arguments
-  --> $DIR/resume-arg-late-bound.rs:15:10
+error[E0308]: mismatched types
+  --> $DIR/resume-arg-late-bound.rs:15:5
    |
-LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {}
-   |                 ------------------------------- required by this bound in `test`
-...
 LL |     test(gen);
-   |          ^^^
-   |          |
-   |          expected signature of `for<'a> fn(&'a mut bool) -> _`
-   |          found signature of `fn(&mut bool) -> _`
+   |     ^^^^ one type is more general than the other
+   |
+   = note: expected type `for<'a> std::ops::Generator<&'a mut bool>`
+              found type `std::ops::Generator<&mut bool>`
+
+error[E0308]: mismatched types
+  --> $DIR/resume-arg-late-bound.rs:15:5
+   |
+LL |     test(gen);
+   |     ^^^^ one type is more general than the other
+   |
+   = note: expected type `for<'a> std::ops::Generator<&'a mut bool>`
+              found type `std::ops::Generator<&mut bool>`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0631`.
+For more information about this error, try `rustc --explain E0308`.
index 1da224a3e85e090fb4df252402381bcefd25d02b..92a85825030c27bf80e890c9b4ce3125c777f2bf 100644 (file)
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:45: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_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32,
 LL | | for<'a>    fn(&'a u32, &'a u32) -> &'a u32) }
index 880a8c7be8305d3e3f1426a44a0a40c86f9b6ed0..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,17 +1,14 @@
-error[E0308]: mismatched types
-  --> $DIR/hr-subtype.rs:45:26
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/hr-subtype.rs:102: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 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index d2abcc4a66091d7800655a40411949384180ebe3..98f5bff732762e808b1b6f20bd0e82d67ab286cf 100644 (file)
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:45: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 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index e1a16f5149cc6069d241a1a8f5a94ce2021e60ee..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,17 +1,14 @@
-error[E0308]: mismatched types
-  --> $DIR/hr-subtype.rs:45:26
+error: fatal error triggered by #[rustc_error]
+  --> $DIR/hr-subtype.rs:102: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 5fec1e9a92eaecbee6332c74d0b6ac80062223fa..100ba6ac27e2530f11ce2d8c3e1e192852b1efef 100644 (file)
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/hr-subtype.rs:45: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_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
 LL | | for<'a>    fn(Inv<'a>, Inv<'a>)) }
index 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index 0cc30e479c7b9ace3702125858f51407ee3b0460..948375566104becb71af12379dc710934c685e3c 100644 (file)
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/hr-subtype.rs:104:1
+  --> $DIR/hr-subtype.rs:102:1
    |
 LL | / fn main() {
 LL | |
index 9e9c2ce9c61d71aa143854a262664fe0e054a389..ad9500eedca935efa09aa76beb3ba29d6b30897b 100644 (file)
@@ -48,8 +48,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_contra_a_contra_b_ret_co_a]~^^^^^^^ ERROR
         }
     };
 }
@@ -109,4 +107,6 @@ fn main() {
     //[free_x_vs_free_x]~^^^^^ ERROR fatal error triggered by #[rustc_error]
     //[bound_co_a_b_vs_bound_co_a]~^^^^^^ ERROR
     //[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR
+    //[bound_a_b_vs_bound_a]~^^^^^^^^ ERROR
+    //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ 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 c0e3fd3cf4679dc3d8d9b70943d1cfd8f2a7e1c1..90a7cadca41b7e43336a55b4674122aa0313e725 100644 (file)
@@ -1,17 +1,43 @@
-error: implementation of `Stream` is not general enough
-  --> $DIR/issue-30786.rs:108:22
+error[E0599]: no method named `filterx` found for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` in the current scope
+  --> $DIR/issue-30786.rs:128:22
    |
-LL | / pub trait Stream {
-LL | |     type Item;
-LL | |     fn next(self) -> Option<Self::Item>;
-LL | | }
-   | |_- trait `Stream` defined here
+LL | pub struct Map<S, F> {
+   | --------------------
+   | |
+   | method `filterx` not found for this
+   | doesn't satisfy `_: StreamExt`
 ...
-LL |       let map = source.map(|x: &_| x);
-   |                        ^^^ implementation of `Stream` is not general enough
+LL |     let filter = map.filterx(|x: &_| true);
+   |                      ^^^^^^^ method not found in `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>`
    |
-   = note: `Stream` would have to be implemented for the type `&'0 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for any lifetime `'0`...
-   = note: ...but `Stream` is actually implemented for the type `&'1 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for some specific lifetime `'1`
+   = note: the method `filterx` exists but the following trait bounds were not satisfied:
+           `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
+           which is required by `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
+           `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
+           which is required by `&Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
+           `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
+           which is required by `&mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
 
-error: aborting due to previous error
+error[E0599]: no method named `countx` found for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` in the current scope
+  --> $DIR/issue-30786.rs:141:24
+   |
+LL | pub struct Filter<S, F> {
+   | -----------------------
+   | |
+   | method `countx` not found for this
+   | doesn't satisfy `_: StreamExt`
+...
+LL |     let count = filter.countx();
+   |                        ^^^^^^ method not found in `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>`
+   |
+   = note: the method `countx` exists but the following trait bounds were not satisfied:
+           `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
+           which is required by `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
+           `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
+           which is required by `&Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
+           `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
+           which is required by `&mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0599`.
index c736c5479f848a47a0b9cd05927477795f280dc6..90a7cadca41b7e43336a55b4674122aa0313e725 100644 (file)
@@ -1,56 +1,43 @@
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:108:15
-   |
-LL |     let map = source.map(|x: &_| x);
-   |               ^^^^^^^^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:114:18
-   |
-LL |     let filter = map.filter(|x: &_| true);
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:114:18
-   |
-LL |     let filter = map.filter(|x: &_| true);
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:114:18
-   |
-LL |     let filter = map.filter(|x: &_| true);
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:114:18
-   |
-LL |     let filter = map.filter(|x: &_| true);
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:119:17
-   |
-LL |     let count = filter.count(); // Assert that we still have a valid stream.
-   |                 ^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:119:17
-   |
-LL |     let count = filter.count(); // Assert that we still have a valid stream.
-   |                 ^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:119:17
-   |
-LL |     let count = filter.count(); // Assert that we still have a valid stream.
-   |                 ^^^^^^^^^^^^^^
-
-error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:119:17
-   |
-LL |     let count = filter.count(); // Assert that we still have a valid stream.
-   |                 ^^^^^^^^^^^^^^
-
-error: aborting due to 9 previous errors
-
+error[E0599]: no method named `filterx` found for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` in the current scope
+  --> $DIR/issue-30786.rs:128:22
+   |
+LL | pub struct Map<S, F> {
+   | --------------------
+   | |
+   | method `filterx` not found for this
+   | doesn't satisfy `_: StreamExt`
+...
+LL |     let filter = map.filterx(|x: &_| true);
+   |                      ^^^^^^^ method not found in `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>`
+   |
+   = note: the method `filterx` exists but the following trait bounds were not satisfied:
+           `&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
+           which is required by `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
+           `&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
+           which is required by `&Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
+           `&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
+           which is required by `&mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: StreamExt`
+
+error[E0599]: no method named `countx` found for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` in the current scope
+  --> $DIR/issue-30786.rs:141:24
+   |
+LL | pub struct Filter<S, F> {
+   | -----------------------
+   | |
+   | method `countx` not found for this
+   | doesn't satisfy `_: StreamExt`
+...
+LL |     let count = filter.countx();
+   |                        ^^^^^^ method not found in `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>`
+   |
+   = note: the method `countx` exists but the following trait bounds were not satisfied:
+           `&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
+           which is required by `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
+           `&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
+           which is required by `&Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
+           `&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
+           which is required by `&mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
index c656f8430653629be8124a5b4114d9276921454a..8ce5c090b543edcd646a7c3d65809e8323ab9b53 100644 (file)
@@ -16,7 +16,7 @@
 
 //[nll]compile-flags: -Z borrowck=mir
 
-pub trait Stream { //[migrate]~ NOTE trait `Stream` defined here
+pub trait Stream {
     type Item;
     fn next(self) -> Option<Self::Item>;
 }
@@ -37,8 +37,9 @@ pub struct Map<S, F> {
 }
 
 impl<'a, A, F, T> Stream for &'a mut Map<A, F>
-where &'a mut A: Stream,
-      F: FnMut(<&'a mut A as Stream>::Item) -> T,
+where
+    &'a mut A: Stream,
+    F: FnMut(<&'a mut A as Stream>::Item) -> T,
 {
     type Item = T;
     fn next(self) -> Option<T> {
@@ -55,8 +56,9 @@ pub struct Filter<S, F> {
 }
 
 impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
-where for<'b> &'b mut A: Stream<Item=T>, // <---- BAD
-      F: FnMut(&T) -> bool,
+where
+    for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
+    F: FnMut(&T) -> bool,
 {
     type Item = <&'a mut A as Stream>::Item;
     fn next(self) -> Option<Self::Item> {
@@ -69,29 +71,29 @@ fn next(self) -> Option<Self::Item> {
     }
 }
 
-pub trait StreamExt where for<'b> &'b mut Self: Stream {
-    fn map<F>(self, func: F) -> Map<Self, F>
-    where Self: Sized,
-    for<'a> &'a mut Map<Self, F>: Stream,
+pub trait StreamExt
+where
+    for<'b> &'b mut Self: Stream,
+{
+    fn mapx<F>(self, func: F) -> Map<Self, F>
+    where
+        Self: Sized,
+        for<'a> &'a mut Map<Self, F>: Stream,
     {
-        Map {
-            func: func,
-            stream: self,
-        }
+        Map { func: func, stream: self }
     }
 
-    fn filter<F>(self, func: F) -> Filter<Self, F>
-    where Self: Sized,
-    for<'a> &'a mut Filter<Self, F>: Stream,
+    fn filterx<F>(self, func: F) -> Filter<Self, F>
+    where
+        Self: Sized,
+        for<'a> &'a mut Filter<Self, F>: Stream,
     {
-        Filter {
-            func: func,
-            stream: self,
-        }
+        Filter { func: func, stream: self }
     }
 
-    fn count(mut self) -> usize
-    where Self: Sized,
+    fn countx(mut self) -> usize
+    where
+        Self: Sized,
     {
         let mut count = 0;
         while let Some(_) = self.next() {
@@ -101,24 +103,44 @@ fn count(mut self) -> usize
     }
 }
 
-impl<T> StreamExt for T where for<'a> &'a mut T: Stream { }
+impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
 
-fn main() {
+fn identity<T>(x: &T) -> &T {
+    x
+}
+
+fn variant1() {
     let source = Repeat(10);
-    let map = source.map(|x: &_| x);
-    //[nll]~^ ERROR higher-ranked subtype error
-    //[migrate]~^^ ERROR implementation of `Stream` is not general enough
-    //[migrate]~| NOTE  `Stream` would have to be implemented for the type `&'0 mut Map
-    //[migrate]~| NOTE  but `Stream` is actually implemented for the type `&'1
-    //[migrate]~| NOTE  implementation of `Stream` is not general enough
-    let filter = map.filter(|x: &_| true);
-    //[nll]~^ ERROR higher-ranked subtype error
-    //[nll]~| ERROR higher-ranked subtype error
-    //[nll]~| ERROR higher-ranked subtype error
-    //[nll]~| ERROR higher-ranked subtype error
-    let count = filter.count(); // Assert that we still have a valid stream.
-    //[nll]~^ ERROR higher-ranked subtype error
-    //[nll]~| ERROR higher-ranked subtype error
-    //[nll]~| ERROR higher-ranked subtype error
-    //[nll]~| ERROR higher-ranked subtype error
+
+    // Here, the call to `mapx` returns a type `T` to which `StreamExt`
+    // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold.
+    //
+    // More concretely, the type `T` is `Map<Repeat, Closure>`, and
+    // the where clause doesn't hold because the signature of the
+    // closure gets inferred to a signature like `|&'_ Stream| -> &'_`
+    // for some specific `'_`, rather than a more generic
+    // signature.
+    //
+    // Why *exactly* we opt for this signature is a bit unclear to me,
+    // we deduce it somehow from a reuqirement that `Map: Stream` I
+    // guess.
+    let map = source.mapx(|x: &_| x);
+    let filter = map.filterx(|x: &_| true);
+    //[migrate]~^ ERROR no method named `filterx`
+    //[nll]~^^ ERROR no method named `filterx`
 }
+
+fn variant2() {
+    let source = Repeat(10);
+
+    // Here, we use a function, which is not subject to the vagaries
+    // of closure signature inference. In this case, we get the error
+    // on `countx` as, I think, the test originally expected.
+    let map = source.mapx(identity);
+    let filter = map.filterx(|x: &_| true);
+    let count = filter.countx();
+    //[migrate]~^ ERROR no method named `countx`
+    //[nll]~^^ ERROR no method named `countx`
+}
+
+fn main() {}
index 983fdb13083a1a9eaff415ddabb3a1bcbe32b9ce..3eb3482ac910ea030b1c72c1ced510d5175160dd 100644 (file)
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
   --> $DIR/issue-40000.rs:6:9
    |
 LL |     foo(bar);
-   |         ^^^ expected concrete lifetime, found bound lifetime parameter
+   |         ^^^ one type is more general than the other
    |
-   = note: expected struct `std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r i32) + 'static)>`
-              found struct `std::boxed::Box<dyn std::ops::Fn(_)>`
+   = note: expected trait object `dyn for<'r> std::ops::Fn(&'r i32)`
+              found trait object `dyn std::ops::Fn(&i32)`
 
 error: aborting due to previous error
 
index b259e9e269d06836ad5447cd5ca074da0f7f260d..99cae46fd9cf2b9c33d7f0704ee44d6b0ba6e43f 100644 (file)
@@ -9,11 +9,12 @@ impl<'a> Trait<'a> for Type {
 }
 
 pub fn break_me<T, F>(f: F)
-where T: for<'b> Trait<'b>,
-      F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
+where
+    T: for<'b> Trait<'b>,
+    F: for<'b> FnMut(<T as Trait<'b>>::Assoc),
+{
     break_me::<Type, fn(_)>;
     //~^ ERROR: type mismatch in function arguments
-    //~| ERROR: type mismatch resolving
 }
 
 fn main() {}
index 99fb2a1f5d030fc3889f44e1507e881e10ef37b5..80aca482b3d29b8c8e614353bd7e9f4360d02178 100644 (file)
@@ -1,29 +1,18 @@
 error[E0631]: type mismatch in function arguments
-  --> $DIR/issue-43623.rs:14:5
+  --> $DIR/issue-43623.rs:16:5
    |
 LL | pub fn break_me<T, F>(f: F)
    |        -------- required by a bound in this
-LL | where T: for<'b> Trait<'b>,
-LL |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
-   |          -------------------------------------- required by this bound in `break_me`
+...
+LL |     F: for<'b> FnMut(<T as Trait<'b>>::Assoc),
+   |                ------------------------------ required by this bound in `break_me`
+LL | {
 LL |     break_me::<Type, fn(_)>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |     |
-   |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
-   |     found signature of `fn(_) -> _`
+   |     expected signature of `fn(<Type as Trait<'b>>::Assoc) -> _`
+   |     found signature of `fn(()) -> _`
 
-error[E0271]: type mismatch resolving `for<'b> <fn(_) as std::ops::FnOnce<(<Type as Trait<'b>>::Assoc,)>>::Output == ()`
-  --> $DIR/issue-43623.rs:14:5
-   |
-LL | pub fn break_me<T, F>(f: F)
-   |        -------- required by a bound in this
-LL | where T: for<'b> Trait<'b>,
-LL |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
-   |                  ------------------------------ required by this bound in `break_me`
-LL |     break_me::<Type, fn(_)>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0271, E0631.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0631`.
index e5a9caa32fae701643bc10721e7c6583b227feb9..9c2b2dc9f4daec0b3fc68c30a25d26694002bdc1 100644 (file)
@@ -7,11 +7,13 @@ impl<'a> Trait<'a> for () {
 }
 
 pub fn foo<T, F>(_: T, _: F)
-where T: for<'a> Trait<'a>,
-      F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
+where
+    T: for<'a> Trait<'a>,
+    F: for<'a> FnMut(<T as Trait<'a>>::Item),
+{
+}
 
 fn main() {
     foo((), drop)
     //~^ ERROR type mismatch in function arguments
-    //~| ERROR type mismatch resolving
 }
index e74a34e247a6763e3381b031daaca69dd7854db2..ad679bfa22063cd39d21f78c34dd65002fba3cf5 100644 (file)
@@ -1,31 +1,18 @@
 error[E0631]: type mismatch in function arguments
-  --> $DIR/issue-60283.rs:14:13
+  --> $DIR/issue-60283.rs:17:13
    |
 LL | pub fn foo<T, F>(_: T, _: F)
    |        --- required by a bound in this
-LL | where T: for<'a> Trait<'a>,
-LL |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   |          ------------------------------------- required by this bound in `foo`
+...
+LL |     F: for<'a> FnMut(<T as Trait<'a>>::Item),
+   |                ----------------------------- required by this bound in `foo`
 ...
 LL |     foo((), drop)
    |             ^^^^
    |             |
-   |             expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |             found signature of `fn(_) -> _`
-
-error[E0271]: type mismatch resolving `for<'a> <fn(_) {std::mem::drop::<_>} as std::ops::FnOnce<(<() as Trait<'a>>::Item,)>>::Output == ()`
-  --> $DIR/issue-60283.rs:14:5
-   |
-LL | pub fn foo<T, F>(_: T, _: F)
-   |        --- required by a bound in this
-LL | where T: for<'a> Trait<'a>,
-LL |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   |                  ----------------------------- required by this bound in `foo`
-...
-LL |     foo((), drop)
-   |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
+   |             expected signature of `fn(<() as Trait<'a>>::Item) -> _`
+   |             found signature of `fn(()) -> _`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0271, E0631.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0631`.
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..f9ad4e5814eeb0d0c03aa2b1ed8bd70d4778bd07 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
+   | |              ^ one type is more general than the other
 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 fn pointer `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 65c797f6b19d70083531f76d7c1fa928aa850d81..81f07df3f50bfbbc0f88539232909dffc1551e40 100644 (file)
@@ -1,18 +1,25 @@
-error[E0308]: `match` arms have incompatible types
-  --> $DIR/old-lub-glb-object.rs:12:14
+error[E0308]: mismatched types
+  --> $DIR/old-lub-glb-object.rs:10:13
    |
 LL |       let z = match 22 {
-   |  _____________-
+   |  _____________^
 LL | |         0 => x,
-   | |              - this is found to be of type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
 LL | |         _ => y,
-   | |              ^ expected bound lifetime parameter 'a, found concrete lifetime
 LL | |     };
-   | |_____- `match` arms have incompatible types
+   | |_____^ one type is more general than the other
    |
-   = note:   expected type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
-           found reference `&dyn for<'a> Foo<&'a u8, &'a u8>`
+   = note: expected trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+              found trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/old-lub-glb-object.rs:22:14
+   |
+LL |         0 => x as &dyn for<'a> Foo<&'a u8, &'a u8>,
+   |              ^ one type is more general than the other
+   |
+   = note: expected trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
+              found trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
index 521bd3695dfe5316763e698bd27d199fa1d5c79a..fd4463b63e10e506a74b607bf410e57866bedc53 100644 (file)
@@ -8,5 +8,4 @@ fn main() {
 fn baz<F: Fn(*mut &u32)>(_: F) {}
 fn _test<'a>(f: fn(*mut &'a u32)) {
     baz(f); //~ ERROR type mismatch
-     //~| ERROR type mismatch
 }
index 69a4b458ebf5089a0c3a33e1f6ebe7ccaab2d56a..503899af33ed76301551035fd738c8bce4e8d455 100644 (file)
@@ -22,18 +22,6 @@ LL |     a.iter().map(|_: (u16, u16)| 45);
    |              |
    |              expected signature of `fn(&(u32, u32)) -> _`
 
-error[E0631]: type mismatch in function arguments
-  --> $DIR/closure-arg-type-mismatch.rs:10:9
-   |
-LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   |           ------------- required by this bound in `baz`
-LL | fn _test<'a>(f: fn(*mut &'a u32)) {
-LL |     baz(f);
-   |         ^
-   |         |
-   |         expected signature of `for<'r> fn(*mut &'r u32) -> _`
-   |         found signature of `fn(*mut &'a u32) -> _`
-
 error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()`
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
@@ -43,7 +31,7 @@ LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0271, E0631.
 For more information about an error, try `rustc --explain E0271`.
index 40a4641fe719602f3991dc7a49478f3d5dfafc54..cb2cb228c62e1a842241bfee207bb9f95d20556f 100644 (file)
@@ -6,5 +6,4 @@ fn baz<T: Foo>(_: T) {}
 
 fn main() {
     baz(|_| ()); //~ ERROR type mismatch
-    //~^ ERROR type mismatch
 }
index 389b21574465aa7bc8e94244fb401313eaa8f633..7fab9490ac93f4a5c1a2dfb0d26dc13f7019fce1 100644 (file)
@@ -9,20 +9,6 @@ LL |     baz(|_| ());
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]`
 
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/closure-mismatch.rs:8:5
-   |
-LL | fn baz<T: Foo>(_: T) {}
-   |           --- required by this bound in `baz`
-...
-LL |     baz(|_| ());
-   |     ^^^ ------ found signature of `fn(_) -> _`
-   |     |
-   |     expected signature of `for<'r> fn(&'r ()) -> _`
-   |
-   = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0271, E0631.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0271`.
index 6d75ace3c469814ac21e13a1848bc689e57ee72c..c9ce936c7d43fc06e0691eb6304ae940d71fd50e 100644 (file)
@@ -2,10 +2,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 previous error
 
index 159d32b50b03c5da035e3f52cf88871689c55935..b83e07663faba54cd662b74a0010c5818830e8dc 100644 (file)
@@ -20,12 +20,10 @@ error[E0308]: mismatched types
   --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
    |
 LL |     let _: fn(&mut &isize, &mut &isize) = a;
-   |            ----------------------------   ^ expected concrete lifetime, found bound lifetime parameter
-   |            |
-   |            expected due to this
+   |                                           ^ one type is more general than the other
    |
    = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
-                 found fn item `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}`
+              found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
 
 error: aborting due to 3 previous errors
 
index dda6129e195369e1848b738f139dc3032407865d..c93f2890f1110082975608d909ee967f41d4c44b 100644 (file)
@@ -31,12 +31,10 @@ error[E0308]: mismatched types
   --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
    |
 LL |     let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
-   |            -----------------------------------------   ^ expected concrete lifetime, found bound lifetime parameter
-   |            |
-   |            expected due to this
+   |                                                        ^ one type is more general than the other
    |
    = note: expected fn pointer `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)`
-                 found fn item `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}`
+              found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
 
 error: aborting due to 4 previous errors
 
index 01f43aeebaf7cb3a77a051efd20bd81149cf9082..2b2dd0dbbf2509ed209d24e1cf3963003fab6aed 100644 (file)
@@ -20,12 +20,10 @@ error[E0308]: mismatched types
   --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43
    |
 LL |     let _: fn(&mut &isize, &mut &isize) = a;
-   |            ----------------------------   ^ expected concrete lifetime, found bound lifetime parameter
-   |            |
-   |            expected due to this
+   |                                           ^ one type is more general than the other
    |
    = note: expected fn pointer `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
-                 found fn item `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}`
+              found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
 
 error: aborting due to 3 previous errors
 
index 55f5d0b94dcb05b72c3e1b5762f1de2a5722f029..0564d53b944e62746a0226df14938477681bc88c 100644 (file)
@@ -8,7 +8,6 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 {
 static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 =
     &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8);
 
-
 struct SomeStruct<'x, 'y, 'z: 'x> {
     foo: &'x Foo<'z>,
     bar: &'x Bar<'z>,
@@ -19,12 +18,12 @@ fn id<T>(t: T) -> T {
     t
 }
 
-static SOME_STRUCT: &SomeStruct = SomeStruct { //~ ERROR mismatched types
+static SOME_STRUCT: &SomeStruct = SomeStruct {
+    //~^ ERROR mismatched types
     foo: &Foo { bools: &[false, true] },
     bar: &Bar { bools: &[true, true] },
     f: &id,
-    //~^ ERROR type mismatch in function arguments
-    //~| ERROR type mismatch resolving
+    //~^ ERROR type mismatch resolving
 };
 
 // very simple test for a 'static static with default lifetime
index 75df99137179b6b08d7c18a81a4d46a6c00ff2d1..90dc7cbfa5521574a50456b6d9f34fd7844a95ec 100644 (file)
@@ -1,46 +1,35 @@
 error[E0308]: mismatched types
-  --> $DIR/rfc1623.rs:22:35
+  --> $DIR/rfc1623.rs:21:35
    |
 LL |   static SOME_STRUCT: &SomeStruct = SomeStruct {
    |  ___________________________________^
+LL | |
 LL | |     foo: &Foo { bools: &[false, true] },
 LL | |     bar: &Bar { bools: &[true, true] },
 LL | |     f: &id,
 LL | |
-LL | |
 LL | | };
    | |_^ expected `&SomeStruct<'static, 'static, 'static>`, found struct `SomeStruct`
    |
 help: consider borrowing here
    |
 LL | static SOME_STRUCT: &SomeStruct = &SomeStruct {
+LL |
 LL |     foo: &Foo { bools: &[false, true] },
 LL |     bar: &Bar { bools: &[true, true] },
 LL |     f: &id,
-LL |
 LL |
  ...
 
-error[E0631]: type mismatch in function arguments
-  --> $DIR/rfc1623.rs:25:8
-   |
-LL | fn id<T>(t: T) -> T {
-   | ------------------- found signature of `fn(_) -> _`
-...
-LL |     f: &id,
-   |        ^^^ expected signature of `for<'a, 'b> fn(&'a Foo<'b>) -> _`
-   |
-   = note: required for the cast to the object type `dyn for<'a, 'b> std::ops::Fn(&'a Foo<'b>) -> &'a Foo<'b>`
-
-error[E0271]: type mismatch resolving `for<'a, 'b> <fn(_) -> _ {id::<_>} as std::ops::FnOnce<(&'a Foo<'b>,)>>::Output == &'a Foo<'b>`
+error[E0271]: type mismatch resolving `for<'a, 'b> <fn(&Foo<'_>) -> &Foo<'_> {id::<&Foo<'_>>} as std::ops::FnOnce<(&'a Foo<'b>,)>>::Output == &'a Foo<'b>`
   --> $DIR/rfc1623.rs:25:8
    |
 LL |     f: &id,
-   |        ^^^ expected bound lifetime parameter 'b, found concrete lifetime
+   |        ^^^ expected bound lifetime parameter 'a, found concrete lifetime
    |
    = note: required for the cast to the object type `dyn for<'a, 'b> std::ops::Fn(&'a Foo<'b>) -> &'a Foo<'b>`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0271, E0308, E0631.
+Some errors have detailed explanations: E0271, E0308.
 For more information about an error, try `rustc --explain E0271`.
index 1c2051e7eaeebef25bdef7008e334b58493be71a..84111b1aef8d4cf2b9ef9edddf1348bad549b2a8 100644 (file)
@@ -14,7 +14,7 @@ trait Foo {
 struct X;
 
 impl Foo for X {
-    type Bar = impl Baz<Self, Self>; //~ ERROR type mismatch in closure arguments
+    type Bar = impl Baz<Self, Self>;
     //~^ ERROR type mismatch resolving
 
     fn bar(&self) -> Self::Bar {
index cc121ac89fb8d756033655c89870fb82000950dc..3cb8abcdcfd1751bbbda4a4276825aba44501714 100644 (file)
@@ -1,14 +1,3 @@
-error[E0631]: type mismatch in closure arguments
-  --> $DIR/issue-57611-trait-alias.rs:17:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _`
-...
-LL |         |x| x
-   |         ----- found signature of `fn(_) -> _`
-   |
-   = note: the return type of a function must have a statically known size
-
 error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-57611-trait-alias.rs:21:9: 21:14] as std::ops::FnOnce<(&'r X,)>>::Output == &'r X`
   --> $DIR/issue-57611-trait-alias.rs:17:16
    |
@@ -17,7 +6,6 @@ LL |     type Bar = impl Baz<Self, Self>;
    |
    = note: the return type of a function must have a statically known size
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0271, E0631.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0271`.
index a6e26614a6a50bd6122e64110f3da370b924d8cd..e2082d4f78e7026bac85bd273ee34027880b416b 100644 (file)
@@ -1,23 +1,29 @@
 // Tests that unsafe extern fn pointers do not implement any Fn traits.
 
-use std::ops::{Fn,FnMut,FnOnce};
+use std::ops::{Fn, FnMut, FnOnce};
 
-unsafe fn square(x: &isize) -> isize { (*x) * (*x) }
+unsafe fn square(x: &isize) -> isize {
+    (*x) * (*x)
+}
 
-fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
+fn call_it<F: Fn(&isize) -> isize>(_: &F, _: isize) -> isize {
+    0
+}
+fn call_it_mut<F: FnMut(&isize) -> isize>(_: &mut F, _: isize) -> isize {
+    0
+}
+fn call_it_once<F: FnOnce(&isize) -> isize>(_: F, _: isize) -> isize {
+    0
+}
 
 fn a() {
     let x = call_it(&square, 22);
     //~^ ERROR E0277
-    //~| ERROR expected
 }
 
 fn b() {
     let y = call_it_mut(&mut square, 22);
     //~^ ERROR E0277
-    //~| ERROR expected
 }
 
 fn c() {
@@ -25,4 +31,4 @@ fn c() {
     //~^ ERROR E0277
 }
 
-fn main() { }
+fn main() {}
index b9ee9e460201a371c1dc89536ffb4aec9cb69489..b06f745e7c1f184f56a096ddd3272d0cd12e527d 100644 (file)
@@ -1,30 +1,19 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:21
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:20:21
    |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   |              ----------------- required by this bound in `call_it`
+LL | fn call_it<F: Fn(&isize) -> isize>(_: &F, _: isize) -> isize {
+   |               ------------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
-error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:21
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   |                          ----- required by this bound in `call_it`
-...
-LL |     let x = call_it(&square, 22);
-   |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-   |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:25
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:25:25
    |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   |                  -------------------- required by this bound in `call_it_mut`
+LL | fn call_it_mut<F: FnMut(&isize) -> isize>(_: &mut F, _: isize) -> isize {
+   |                   ---------------------- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
@@ -32,27 +21,16 @@ LL |     let y = call_it_mut(&mut square, 22);
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:25
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   |                                 ----- required by this bound in `call_it_mut`
-...
-LL |     let y = call_it_mut(&mut square, 22);
-   |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-   |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-
-error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:26
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:30:26
    |
-LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   |                                   ----- required by this bound in `call_it_once`
+LL | fn call_it_once<F: FnOnce(&isize) -> isize>(_: F, _: isize) -> isize {
+   |                    ----------------------- required by this bound in `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
    |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
index dd3b1afc39f3114fed39a0992589ec2eeb0ae045..dd76c597d28ad1f461d31858fcdcd66cf5daded3 100644 (file)
@@ -1,23 +1,29 @@
 // Tests that unsafe extern fn pointers do not implement any Fn traits.
 
-use std::ops::{Fn,FnMut,FnOnce};
+use std::ops::{Fn, FnMut, FnOnce};
 
-extern "C" fn square(x: &isize) -> isize { (*x) * (*x) }
+extern "C" fn square(x: &isize) -> isize {
+    (*x) * (*x)
+}
 
-fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
+fn call_it<F: Fn(&isize) -> isize>(_: &F, _: isize) -> isize {
+    0
+}
+fn call_it_mut<F: FnMut(&isize) -> isize>(_: &mut F, _: isize) -> isize {
+    0
+}
+fn call_it_once<F: FnOnce(&isize) -> isize>(_: F, _: isize) -> isize {
+    0
+}
 
 fn a() {
     let x = call_it(&square, 22);
     //~^ ERROR E0277
-    //~| ERROR expected
 }
 
 fn b() {
     let y = call_it_mut(&mut square, 22);
     //~^ ERROR E0277
-    //~| ERROR expected
 }
 
 fn c() {
@@ -25,4 +31,4 @@ fn c() {
     //~^ ERROR E0277
 }
 
-fn main() { }
+fn main() {}
index 654b626cf65ccd6ad447c648d12ae4b4c3256fe4..8f6945cda806c69aa4956039d634ab20f58cd820 100644 (file)
@@ -1,30 +1,19 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:12:21
+  --> $DIR/unboxed-closures-wrong-abi.rs:20:21
    |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   |              ----------------- required by this bound in `call_it`
+LL | fn call_it<F: Fn(&isize) -> isize>(_: &F, _: isize) -> isize {
+   |               ------------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
-error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:12:21
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   |                          ----- required by this bound in `call_it`
-...
-LL |     let x = call_it(&square, 22);
-   |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-   |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:18:25
+  --> $DIR/unboxed-closures-wrong-abi.rs:25:25
    |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   |                  -------------------- required by this bound in `call_it_mut`
+LL | fn call_it_mut<F: FnMut(&isize) -> isize>(_: &mut F, _: isize) -> isize {
+   |                   ---------------------- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
@@ -32,27 +21,16 @@ LL |     let y = call_it_mut(&mut square, 22);
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:18:25
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   |                                 ----- required by this bound in `call_it_mut`
-...
-LL |     let y = call_it_mut(&mut square, 22);
-   |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-   |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-
-error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:24:26
+  --> $DIR/unboxed-closures-wrong-abi.rs:30:26
    |
-LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   |                                   ----- required by this bound in `call_it_once`
+LL | fn call_it_once<F: FnOnce(&isize) -> isize>(_: F, _: isize) -> isize {
+   |                    ----------------------- required by this bound in `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
    |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
index c689d79266187ccb9e82c36b64b4eed07f7f3591..02e8b7b47ae19843a9ef1215eeb2aaf578e917f0 100644 (file)
@@ -1,24 +1,30 @@
 // Tests that unsafe extern fn pointers do not implement any Fn traits.
 
-use std::ops::{Fn,FnMut,FnOnce};
+use std::ops::{Fn, FnMut, FnOnce};
 
-unsafe fn square(x: isize) -> isize { x * x }
+unsafe fn square(x: isize) -> isize {
+    x * x
+}
 // note: argument type here is `isize`, not `&isize`
 
-fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
+fn call_it<F: Fn(&isize) -> isize>(_: &F, _: isize) -> isize {
+    0
+}
+fn call_it_mut<F: FnMut(&isize) -> isize>(_: &mut F, _: isize) -> isize {
+    0
+}
+fn call_it_once<F: FnOnce(&isize) -> isize>(_: F, _: isize) -> isize {
+    0
+}
 
 fn a() {
     let x = call_it(&square, 22);
     //~^ ERROR E0277
-    //~| ERROR expected
 }
 
 fn b() {
     let y = call_it_mut(&mut square, 22);
     //~^ ERROR E0277
-    //~| ERROR expected
 }
 
 fn c() {
@@ -26,4 +32,4 @@ fn c() {
     //~^ ERROR E0277
 }
 
-fn main() { }
+fn main() {}
index 434c8a579f67139b8702148e8efa8e30eb0cde39..93a645b485ef0374ea65871ada6bc3a3a8b6b5ea 100644 (file)
@@ -1,30 +1,19 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:21
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:21:21
    |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   |              ----------------- required by this bound in `call_it`
+LL | fn call_it<F: Fn(&isize) -> isize>(_: &F, _: isize) -> isize {
+   |               ------------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
-error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:21
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   |                          ----- required by this bound in `call_it`
-...
-LL |     let x = call_it(&square, 22);
-   |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-   |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:25
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:26:25
    |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   |                  -------------------- required by this bound in `call_it_mut`
+LL | fn call_it_mut<F: FnMut(&isize) -> isize>(_: &mut F, _: isize) -> isize {
+   |                   ---------------------- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
@@ -32,27 +21,16 @@ LL |     let y = call_it_mut(&mut square, 22);
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:25
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   |                                 ----- required by this bound in `call_it_mut`
-...
-LL |     let y = call_it_mut(&mut square, 22);
-   |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-   |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-
-error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:26
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:31:26
    |
-LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   |                                   ----- required by this bound in `call_it_once`
+LL | fn call_it_once<F: FnOnce(&isize) -> isize>(_: F, _: isize) -> isize {
+   |                    ----------------------- required by this bound in `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
    |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
-   = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
+   = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.