From: Niko Matsakis Date: Wed, 20 May 2020 10:19:36 +0000 (+0000) Subject: move leak-check to during coherence, candidate eval X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=5a7a850753b60abfd2a806bf6bba4259d3535e7b;p=rust.git move leak-check to during coherence, candidate eval 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 `::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 --- diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/src/librustc_infer/infer/higher_ranked/mod.rs index b94221785ae..b6251e34008 100644 --- a/src/librustc_infer/infer/higher_ranked/mod.rs +++ b/src/librustc_infer/infer/higher_ranked/mod.rs @@ -30,7 +30,7 @@ pub fn higher_ranked_sub( 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( // 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( 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( 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={:?}, \ diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/src/librustc_infer/infer/region_constraints/leak_check.rs index f3b78909b42..32e708bf52b 100644 --- a/src/librustc_infer/infer/region_constraints/leak_check.rs +++ b/src/librustc_infer/infer/region_constraints/leak_check.rs @@ -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 { diff --git a/src/librustc_trait_selection/traits/coherence.rs b/src/librustc_trait_selection/traits/coherence.rs index 706cbf058b7..3ec7fe2bf25 100644 --- a/src/librustc_trait_selection/traits/coherence.rs +++ b/src/librustc_trait_selection/traits/coherence.rs @@ -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); diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 4bc58fbaadc..ae255c22f9d 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -298,11 +298,7 @@ fn new( fn fold>(&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) } } } diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index e90acbbce67..e5960e73103 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -347,6 +347,12 @@ fn evaluation_probe( ) -> Result { self.infcx.probe(|snapshot| -> Result { 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 } } } diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index 50f1d07142f..315d180844d 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -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::(); - | ^^^^^^^^^^^^^^^^^^ 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 diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr index 5009e0868a7..9462121bdf2 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr @@ -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 diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr index 8f445acf2b9..2156ecb1739 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.ok.stderr @@ -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 diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr index 65d16440ac9..64b57223908 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr @@ -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 diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs index 23d873212ed..0034d796826 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs @@ -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 &'a u32> + data: PhantomData &'a u32>, } -fn foo<'a>() -> Type<'a> { loop { } } +fn foo<'a>() -> Type<'a> { + loop {} +} fn bar(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] diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 0a05fc6bb82..ef57f9e0bc4 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -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<'_>` diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs index a4e43da91ba..c81c40c18b4 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs @@ -1,10 +1,12 @@ fn with_closure_expecting_fn_with_free_region(_: 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) - 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() {} diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr index fae41c4114a..0de15dfa735 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr @@ -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) - | ------------------------------------------ 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) - | ------------------------------------------- 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) - | ------------------------------------------- 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`. diff --git a/src/test/ui/closures/issue-41366.rs b/src/test/ui/closures/issue-41366.rs index 5cae0e76d1a..af1e37ba867 100644 --- a/src/test/ui/closures/issue-41366.rs +++ b/src/test/ui/closures/issue-41366.rs @@ -7,7 +7,6 @@ impl<'g> T<'g> for u32 { } fn main() { - (&|_|()) as &dyn for<'x> Fn(>::V); + (&|_| ()) as &dyn for<'x> Fn(>::V); //~^ ERROR: type mismatch in closure arguments - //~| ERROR: type mismatch resolving } diff --git a/src/test/ui/closures/issue-41366.stderr b/src/test/ui/closures/issue-41366.stderr index 2f2871e9f0e..9c4b7d529ef 100644 --- a/src/test/ui/closures/issue-41366.stderr +++ b/src/test/ui/closures/issue-41366.stderr @@ -1,23 +1,14 @@ error[E0631]: type mismatch in closure arguments --> $DIR/issue-41366.rs:10:5 | -LL | (&|_|()) as &dyn for<'x> Fn(>::V); - | ^^-----^ +LL | (&|_| ()) as &dyn for<'x> Fn(>::V); + | ^^------^ | | | - | | found signature of `fn(_) -> _` - | expected signature of `for<'x> fn(>::V) -> _` + | | found signature of `fn(u16) -> _` + | expected signature of `fn(>::V) -> _` | = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(>::V)` -error[E0271]: type mismatch resolving `for<'x> <[closure@$DIR/issue-41366.rs:10:7: 10:12] as std::ops::FnOnce<(>::V,)>>::Output == ()` - --> $DIR/issue-41366.rs:10:5 - | -LL | (&|_|()) as &dyn for<'x> Fn(>::V); - | ^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime - | - = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(>::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`. diff --git a/src/test/ui/generator/resume-arg-late-bound.rs b/src/test/ui/generator/resume-arg-late-bound.rs index 87b1f1a065b..a8f657eaabe 100644 --- a/src/test/ui/generator/resume-arg-late-bound.rs +++ b/src/test/ui/generator/resume-arg-late-bound.rs @@ -13,5 +13,6 @@ fn main() { *arg = true; }; test(gen); - //~^ ERROR type mismatch in function arguments + //~^ ERROR mismatched types + //~| ERROR mismatched types } diff --git a/src/test/ui/generator/resume-arg-late-bound.stderr b/src/test/ui/generator/resume-arg-late-bound.stderr index ffa440daed8..c379d9eae8e 100644 --- a/src/test/ui/generator/resume-arg-late-bound.stderr +++ b/src/test/ui/generator/resume-arg-late-bound.stderr @@ -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`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr index 1da224a3e85..92a85825030 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr @@ -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) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr index 880a8c7be83..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr @@ -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 fn(&'a u32, &'b u32)>` - found enum `std::option::Option 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`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr index d2abcc4a660..98f5bff7327 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr @@ -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)) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr index e1a16f5149c..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr @@ -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 fn(Contra<'a>, Contra<'b>) -> Co<'a>>` - found enum `std::option::Option 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`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr index 5fec1e9a92e..100ba6ac27e 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -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>)) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr index 0cc30e479c7..94837556610 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr @@ -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 | | diff --git a/src/test/ui/hr-subtype/hr-subtype.rs b/src/test/ui/hr-subtype/hr-subtype.rs index 9e9c2ce9c61..ad9500eedca 100644 --- a/src/test/ui/hr-subtype/hr-subtype.rs +++ b/src/test/ui/hr-subtype/hr-subtype.rs @@ -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 } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr index 328e98657ef..9914783d976 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr @@ -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)` diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr index c0e3fd3cf46..90a7cadca41 100644 --- a/src/test/ui/hrtb/issue-30786.migrate.stderr +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -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` in the current scope + --> $DIR/issue-30786.rs:128:22 | -LL | / pub trait Stream { -LL | | type Item; -LL | | fn next(self) -> Option; -LL | | } - | |_- trait `Stream` defined here +LL | pub struct Map { + | -------------------- + | | + | 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` | - = note: `Stream` would have to be implemented for the type `&'0 mut Map`, for any lifetime `'0`... - = note: ...but `Stream` is actually implemented for the type `&'1 mut Map`, for some specific lifetime `'1` + = note: the method `filterx` exists but the following trait bounds were not satisfied: + `&'a mut Map: Stream` + which is required by `Map: StreamExt` + `&'a mut &Map: Stream` + which is required by `&Map: StreamExt` + `&'a mut &mut Map: Stream` + which is required by `&mut Map: StreamExt` -error: aborting due to previous error +error[E0599]: no method named `countx` found for struct `Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` in the current scope + --> $DIR/issue-30786.rs:141:24 + | +LL | pub struct Filter { + | ----------------------- + | | + | method `countx` not found for this + | doesn't satisfy `_: StreamExt` +... +LL | let count = filter.countx(); + | ^^^^^^ method not found in `Filter fn(&'r u64) -> &'r u64 {identity::}>, [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 fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + which is required by `Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` + `&'a mut &Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + which is required by `&Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` + `&'a mut &mut Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + which is required by `&mut Filter fn(&'r u64) -> &'r u64 {identity::}>, [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`. diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index c736c5479f8..90a7cadca41 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -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` in the current scope + --> $DIR/issue-30786.rs:128:22 + | +LL | pub struct Map { + | -------------------- + | | + | method `filterx` not found for this + | doesn't satisfy `_: StreamExt` +... +LL | let filter = map.filterx(|x: &_| true); + | ^^^^^^^ method not found in `Map` + | + = note: the method `filterx` exists but the following trait bounds were not satisfied: + `&'a mut Map: Stream` + which is required by `Map: StreamExt` + `&'a mut &Map: Stream` + which is required by `&Map: StreamExt` + `&'a mut &mut Map: Stream` + which is required by `&mut Map: StreamExt` + +error[E0599]: no method named `countx` found for struct `Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` in the current scope + --> $DIR/issue-30786.rs:141:24 + | +LL | pub struct Filter { + | ----------------------- + | | + | method `countx` not found for this + | doesn't satisfy `_: StreamExt` +... +LL | let count = filter.countx(); + | ^^^^^^ method not found in `Filter fn(&'r u64) -> &'r u64 {identity::}>, [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 fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + which is required by `Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` + `&'a mut &Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + which is required by `&Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: StreamExt` + `&'a mut &mut Filter fn(&'r u64) -> &'r u64 {identity::}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream` + which is required by `&mut Filter fn(&'r u64) -> &'r u64 {identity::}>, [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`. diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs index c656f843065..8ce5c090b54 100644 --- a/src/test/ui/hrtb/issue-30786.rs +++ b/src/test/ui/hrtb/issue-30786.rs @@ -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; } @@ -37,8 +37,9 @@ pub struct Map { } impl<'a, A, F, T> Stream for &'a mut Map -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 { @@ -55,8 +56,9 @@ pub struct Filter { } impl<'a, A, F, T> Stream for &'a mut Filter -where for<'b> &'b mut A: Stream, // <---- BAD - F: FnMut(&T) -> bool, +where + for<'b> &'b mut A: Stream, // <---- BAD + F: FnMut(&T) -> bool, { type Item = <&'a mut A as Stream>::Item; fn next(self) -> Option { @@ -69,29 +71,29 @@ fn next(self) -> Option { } } -pub trait StreamExt where for<'b> &'b mut Self: Stream { - fn map(self, func: F) -> Map - where Self: Sized, - for<'a> &'a mut Map: Stream, +pub trait StreamExt +where + for<'b> &'b mut Self: Stream, +{ + fn mapx(self, func: F) -> Map + where + Self: Sized, + for<'a> &'a mut Map: Stream, { - Map { - func: func, - stream: self, - } + Map { func: func, stream: self } } - fn filter(self, func: F) -> Filter - where Self: Sized, - for<'a> &'a mut Filter: Stream, + fn filterx(self, func: F) -> Filter + where + Self: Sized, + for<'a> &'a mut Filter: 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 StreamExt for T where for<'a> &'a mut T: Stream { } +impl StreamExt for T where for<'a> &'a mut T: Stream {} -fn main() { +fn identity(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`, 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() {} diff --git a/src/test/ui/issues/issue-40000.stderr b/src/test/ui/issues/issue-40000.stderr index 983fdb13083..3eb3482ac91 100644 --- a/src/test/ui/issues/issue-40000.stderr +++ b/src/test/ui/issues/issue-40000.stderr @@ -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` + = 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 diff --git a/src/test/ui/issues/issue-43623.rs b/src/test/ui/issues/issue-43623.rs index b259e9e269d..99cae46fd9c 100644 --- a/src/test/ui/issues/issue-43623.rs +++ b/src/test/ui/issues/issue-43623.rs @@ -9,11 +9,12 @@ impl<'a> Trait<'a> for Type { } pub fn break_me(f: F) -where T: for<'b> Trait<'b>, - F: for<'b> FnMut(>::Assoc) { +where + T: for<'b> Trait<'b>, + F: for<'b> FnMut(>::Assoc), +{ break_me::; //~^ ERROR: type mismatch in function arguments - //~| ERROR: type mismatch resolving } fn main() {} diff --git a/src/test/ui/issues/issue-43623.stderr b/src/test/ui/issues/issue-43623.stderr index 99fb2a1f5d0..80aca482b3d 100644 --- a/src/test/ui/issues/issue-43623.stderr +++ b/src/test/ui/issues/issue-43623.stderr @@ -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(f: F) | -------- required by a bound in this -LL | where T: for<'b> Trait<'b>, -LL | F: for<'b> FnMut(>::Assoc) { - | -------------------------------------- required by this bound in `break_me` +... +LL | F: for<'b> FnMut(>::Assoc), + | ------------------------------ required by this bound in `break_me` +LL | { LL | break_me::; | ^^^^^^^^^^^^^^^^^^^^^^^ | | - | expected signature of `for<'b> fn(>::Assoc) -> _` - | found signature of `fn(_) -> _` + | expected signature of `fn(>::Assoc) -> _` + | found signature of `fn(()) -> _` -error[E0271]: type mismatch resolving `for<'b> >::Assoc,)>>::Output == ()` - --> $DIR/issue-43623.rs:14:5 - | -LL | pub fn break_me(f: F) - | -------- required by a bound in this -LL | where T: for<'b> Trait<'b>, -LL | F: for<'b> FnMut(>::Assoc) { - | ------------------------------ required by this bound in `break_me` -LL | break_me::; - | ^^^^^^^^^^^^^^^^^^^^^^^ 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`. diff --git a/src/test/ui/issues/issue-60283.rs b/src/test/ui/issues/issue-60283.rs index e5a9caa32fa..9c2b2dc9f4d 100644 --- a/src/test/ui/issues/issue-60283.rs +++ b/src/test/ui/issues/issue-60283.rs @@ -7,11 +7,13 @@ impl<'a> Trait<'a> for () { } pub fn foo(_: T, _: F) -where T: for<'a> Trait<'a>, - F: for<'a> FnMut(>::Item) {} +where + T: for<'a> Trait<'a>, + F: for<'a> FnMut(>::Item), +{ +} fn main() { foo((), drop) //~^ ERROR type mismatch in function arguments - //~| ERROR type mismatch resolving } diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr index e74a34e247a..ad679bfa220 100644 --- a/src/test/ui/issues/issue-60283.stderr +++ b/src/test/ui/issues/issue-60283.stderr @@ -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) | --- required by a bound in this -LL | where T: for<'a> Trait<'a>, -LL | F: for<'a> FnMut(>::Item) {} - | ------------------------------------- required by this bound in `foo` +... +LL | F: for<'a> FnMut(>::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> } as std::ops::FnOnce<(<() as Trait<'a>>::Item,)>>::Output == ()` - --> $DIR/issue-60283.rs:14:5 - | -LL | pub fn foo(_: T, _: F) - | --- required by a bound in this -LL | where T: for<'a> Trait<'a>, -LL | F: for<'a> FnMut(>::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`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs index bc7b787cd65..5e24a99bcc3 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.rs +++ b/src/test/ui/lub-glb/old-lub-glb-hr.rs @@ -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() { } diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr index 6d5d5117469..f9ad4e5814e 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr @@ -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 diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr index 65c797f6b19..81f07df3f50 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr @@ -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`. diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs index 521bd3695df..fd4463b63e1 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -8,5 +8,4 @@ fn main() { fn baz(_: F) {} fn _test<'a>(f: fn(*mut &'a u32)) { baz(f); //~ ERROR type mismatch - //~| ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 69a4b458ebf..503899af33e 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -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) {} - | ------------- 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> >::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`. diff --git a/src/test/ui/mismatched_types/closure-mismatch.rs b/src/test/ui/mismatched_types/closure-mismatch.rs index 40a4641fe71..cb2cb228c62 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-mismatch.rs @@ -6,5 +6,4 @@ fn baz(_: T) {} fn main() { baz(|_| ()); //~ ERROR type mismatch - //~^ ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 389b2157446..7fab9490ac9 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -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) {} - | --- 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`. diff --git a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr index 6d75ace3c46..c9ce936c7d4 100644 --- a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr +++ b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr @@ -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 diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr index 159d32b50b0..b83e07663fa 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr @@ -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 diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr index dda6129e195..c93f2890f11 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr @@ -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 diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr index 01f43aeebaf..2b2dd0dbbf2 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr @@ -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 diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfc1623.rs index 55f5d0b94dc..0564d53b944 100644 --- a/src/test/ui/rfc1623.rs +++ b/src/test/ui/rfc1623.rs @@ -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 } -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 diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index 75df9913717..90dc7cbfa55 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -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 { - | ------------------- 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> _ {id::<_>} as std::ops::FnOnce<(&'a Foo<'b>,)>>::Output == &'a Foo<'b>` +error[E0271]: type mismatch resolving `for<'a, 'b> ) -> &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`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index 1c2051e7eae..84111b1aef8 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -14,7 +14,7 @@ trait Foo { struct X; impl Foo for X { - type Bar = impl Baz; //~ ERROR type mismatch in closure arguments + type Bar = impl Baz; //~^ ERROR type mismatch resolving fn bar(&self) -> Self::Bar { diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr index cc121ac89fb..3cb8abcdcfd 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -1,14 +1,3 @@ -error[E0631]: type mismatch in closure arguments - --> $DIR/issue-57611-trait-alias.rs:17:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ 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; | = 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`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs index a6e26614a6a..e2082d4f78e 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs @@ -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_itisize>(_: &F, _: isize) -> isize { 0 } -fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } -fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } +fn call_it isize>(_: &F, _: isize) -> isize { + 0 +} +fn call_it_mut isize>(_: &mut F, _: isize) -> isize { + 0 +} +fn call_it_once 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() {} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr index b9ee9e46020..b06f745e7c1 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr @@ -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_itisize>(_: &F, _: isize) -> isize { 0 } - | ----------------- required by this bound in `call_it` +LL | fn call_it 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_itisize>(_: &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_mutisize>(_: &mut F, _: isize) -> isize { 0 } - | -------------------- required by this bound in `call_it_mut` +LL | fn call_it_mut 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_mutisize>(_: &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_onceisize>(_: F, _: isize) -> isize { 0 } - | ----- required by this bound in `call_it_once` +LL | fn call_it_once 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`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs index dd3b1afc39f..dd76c597d28 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs @@ -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_itisize>(_: &F, _: isize) -> isize { 0 } -fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } -fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } +fn call_it isize>(_: &F, _: isize) -> isize { + 0 +} +fn call_it_mut isize>(_: &mut F, _: isize) -> isize { + 0 +} +fn call_it_once 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() {} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr index 654b626cf65..8f6945cda80 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr @@ -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_itisize>(_: &F, _: isize) -> isize { 0 } - | ----------------- required by this bound in `call_it` +LL | fn call_it 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_itisize>(_: &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_mutisize>(_: &mut F, _: isize) -> isize { 0 } - | -------------------- required by this bound in `call_it_mut` +LL | fn call_it_mut 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_mutisize>(_: &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_onceisize>(_: F, _: isize) -> isize { 0 } - | ----- required by this bound in `call_it_once` +LL | fn call_it_once 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`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs index c689d792661..02e8b7b47ae 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs @@ -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_itisize>(_: &F, _: isize) -> isize { 0 } -fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } -fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } +fn call_it isize>(_: &F, _: isize) -> isize { + 0 +} +fn call_it_mut isize>(_: &mut F, _: isize) -> isize { + 0 +} +fn call_it_once 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() {} diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr index 434c8a579f6..93a645b485e 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr @@ -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_itisize>(_: &F, _: isize) -> isize { 0 } - | ----------------- required by this bound in `call_it` +LL | fn call_it 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_itisize>(_: &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_mutisize>(_: &mut F, _: isize) -> isize { 0 } - | -------------------- required by this bound in `call_it_mut` +LL | fn call_it_mut 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_mutisize>(_: &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_onceisize>(_: F, _: isize) -> isize { 0 } - | ----- required by this bound in `call_it_once` +LL | fn call_it_once 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`.