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 `<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
This commit is contained in:
Niko Matsakis 2020-05-20 10:19:36 +00:00
parent f2cf994483
commit 5a7a850753
60 changed files with 507 additions and 572 deletions

View File

@ -30,7 +30,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
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 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
// 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 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
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={:?}, \

View File

@ -286,6 +286,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
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 {

View 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);

View File

@ -298,11 +298,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
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) }
}
}

View File

@ -347,6 +347,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> 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 @@ impl<'o, 'tcx> TraitObligationStackList<'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 }
}
}

View 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

View 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

View 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

View 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

View 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]

View 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<'_>`

View 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() {}

View 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) -> _`
error[E0631]: type mismatch in closure arguments
--> $DIR/expect-fn-supply-fn.rs:37:5
| ^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `fn(&u32)`
found fn pointer `for<'r> fn(&'r u32)`
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) -> _`
error[E0631]: type mismatch in closure arguments
--> $DIR/expect-fn-supply-fn.rs:46:5
| ^^^^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'r> fn(&'r u32)`
found fn pointer `fn(&'x u32)`
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`.

View 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
}

View 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 previous error
error: aborting due to 2 previous errors
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`.

View File

@ -13,5 +13,6 @@ fn main() {
*arg = true;
};
test(gen);
//~^ ERROR type mismatch in function arguments
//~^ ERROR mismatched types
//~| ERROR mismatched types
}

View 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: aborting due to previous error
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>`
For more information about this error, try `rustc --explain E0631`.
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View 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) }

View 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`.

View 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 | |

View 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 | |

View 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)) }

View 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 | |

View 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 | |

View 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 | |

View 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`.

View 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>)) }

View 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 | |

View 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 | |

View File

@ -48,8 +48,6 @@ macro_rules! check {
//[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
}

View 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)`

View 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`.

View File

@ -1,56 +1,43 @@
error: higher-ranked subtype error
--> $DIR/issue-30786.rs:108:15
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 | let map = source.map(|x: &_| x);
| ^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/issue-30786.rs:114:18
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]>`
|
LL | let filter = map.filter(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^
= 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: higher-ranked subtype error
--> $DIR/issue-30786.rs:114:18
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 | let filter = map.filter(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/issue-30786.rs:114:18
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]>`
|
LL | let filter = map.filter(|x: &_| true);
| ^^^^^^^^^^^^^^^^^^^^^^^^
= 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: 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: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0599`.

View 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 @@ where for<'b> &'b mut A: Stream<Item=T>, // <---- BAD
}
}
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 @@ pub trait StreamExt where for<'b> &'b mut Self: Stream {
}
}
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() {
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
fn identity<T>(x: &T) -> &T {
x
}
fn variant1() {
let source = Repeat(10);
// 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() {}

View 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

View 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() {}

View 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 previous error
error: aborting due to 2 previous errors
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`.

View 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
}

View 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(_) -> _`
| expected signature of `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
error: aborting due to previous error
error: aborting due to 2 previous errors
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`.

View 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() {
}

View 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

View 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`.

View 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
}

View 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`.

View File

@ -6,5 +6,4 @@ fn baz<T: Foo>(_: T) {}
fn main() {
baz(|_| ()); //~ ERROR type mismatch
//~^ ERROR type mismatch
}

View 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 previous error
error: aborting due to 2 previous errors
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`.

View 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

View 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

View 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

View 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

View 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

View 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`.

View 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 {

View 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`.

View 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() {}

View 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
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:30:26
|
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
|
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`.

View 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() {}

View 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
--> $DIR/unboxed-closures-wrong-abi.rs:30:26
|
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
|
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`.

View 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() {}

View 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
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:31:26
|
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
|
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`.