Auto merge of #41488 - estebank:closure-args, r=arielb1
Clean up callable type mismatch errors ```rust error[E0593]: closure takes 1 argument but 2 arguments are required here --> ../../src/test/ui/mismatched_types/closure-arg-count.rs:13:15 | 13 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); | ^^^^^^^ -------------------------- takes 1 argument | | | expected closure that takes 2 arguments ``` instead of ```rust error[E0281]: type mismatch: the type `[closure@../../src/test/ui/mismatched_types/closure-arg-count.rs:13:23: 13:49]` implements the trait `for<'r> std::ops::FnMut<(&'r {integer},)>`, but the trait `for<'r, 'r> std::ops::FnMut<(&'r {integer}, &'r {integer})>` is required (expected a tuple with 2 elements, found one with 1 elements) --> ../../src/test/ui/mismatched_types/closure-arg-count.rs:13:15 | 13 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); | ^^^^^^^ ``` Fix #21857, re #24680.
This commit is contained in:
commit
50517d58a2
@ -1049,18 +1049,19 @@ which expected that trait. This error typically occurs when working with
|
||||
`Fn`-based types. Erroneous code example:
|
||||
|
||||
```compile_fail,E0281
|
||||
fn foo<F: Fn()>(x: F) { }
|
||||
fn foo<F: Fn(usize)>(x: F) { }
|
||||
|
||||
fn main() {
|
||||
// type mismatch: the type ... implements the trait `core::ops::Fn<(_,)>`,
|
||||
// but the trait `core::ops::Fn<()>` is required (expected (), found tuple
|
||||
// type mismatch: ... implements the trait `core::ops::Fn<(String,)>`,
|
||||
// but the trait `core::ops::Fn<(usize,)>` is required
|
||||
// [E0281]
|
||||
foo(|y| { });
|
||||
foo(|y: String| { });
|
||||
}
|
||||
```
|
||||
|
||||
The issue in this case is that `foo` is defined as accepting a `Fn` with no
|
||||
arguments, but the closure we attempted to pass to it requires one argument.
|
||||
The issue in this case is that `foo` is defined as accepting a `Fn` with one
|
||||
argument of type `String`, but the closure we attempted to pass to it requires
|
||||
one arguments of type `usize`.
|
||||
"##,
|
||||
|
||||
E0282: r##"
|
||||
@ -1807,6 +1808,20 @@ makes a difference in practice.)
|
||||
[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
|
||||
"##,
|
||||
|
||||
E0593: r##"
|
||||
You tried to supply an `Fn`-based type with an incorrect number of arguments
|
||||
than what was expected. Erroneous code example:
|
||||
|
||||
```compile_fail,E0593
|
||||
fn foo<F: Fn()>(x: F) { }
|
||||
|
||||
fn main() {
|
||||
// [E0593] closure takes 1 argument but 0 arguments are required
|
||||
foo(|y| { });
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
|
||||
use std::fmt;
|
||||
use syntax::ast::{self, NodeId};
|
||||
use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable, TyInfer, TyVar};
|
||||
use ty::error::ExpectedFound;
|
||||
use ty::error::{ExpectedFound, TypeError};
|
||||
use ty::fast_reject;
|
||||
use ty::fold::TypeFolder;
|
||||
use ty::subst::Subst;
|
||||
@ -663,13 +663,54 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
if actual_trait_ref.self_ty().references_error() {
|
||||
return;
|
||||
}
|
||||
struct_span_err!(self.tcx.sess, span, E0281,
|
||||
"type mismatch: the type `{}` implements the trait `{}`, \
|
||||
but the trait `{}` is required ({})",
|
||||
expected_trait_ref.self_ty(),
|
||||
expected_trait_ref,
|
||||
actual_trait_ref,
|
||||
e)
|
||||
let expected_trait_ty = expected_trait_ref.self_ty();
|
||||
let found_span = expected_trait_ty.ty_to_def_id().and_then(|did| {
|
||||
self.tcx.hir.span_if_local(did)
|
||||
});
|
||||
|
||||
if let &TypeError::TupleSize(ref expected_found) = e {
|
||||
// Expected `|x| { }`, found `|x, y| { }`
|
||||
self.report_arg_count_mismatch(span,
|
||||
found_span,
|
||||
expected_found.expected,
|
||||
expected_found.found,
|
||||
expected_trait_ty.is_closure())
|
||||
} else if let &TypeError::Sorts(ref expected_found) = e {
|
||||
let expected = if let ty::TyTuple(tys, _) = expected_found.expected.sty {
|
||||
tys.len()
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let found = if let ty::TyTuple(tys, _) = expected_found.found.sty {
|
||||
tys.len()
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
if expected != found {
|
||||
// Expected `|| { }`, found `|x, y| { }`
|
||||
// Expected `fn(x) -> ()`, found `|| { }`
|
||||
self.report_arg_count_mismatch(span,
|
||||
found_span,
|
||||
expected,
|
||||
found,
|
||||
expected_trait_ty.is_closure())
|
||||
} else {
|
||||
self.report_type_argument_mismatch(span,
|
||||
found_span,
|
||||
expected_trait_ty,
|
||||
expected_trait_ref,
|
||||
actual_trait_ref,
|
||||
e)
|
||||
}
|
||||
} else {
|
||||
self.report_type_argument_mismatch(span,
|
||||
found_span,
|
||||
expected_trait_ty,
|
||||
expected_trait_ref,
|
||||
actual_trait_ref,
|
||||
e)
|
||||
}
|
||||
}
|
||||
|
||||
TraitNotObjectSafe(did) => {
|
||||
@ -681,6 +722,60 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn report_type_argument_mismatch(&self,
|
||||
span: Span,
|
||||
found_span: Option<Span>,
|
||||
expected_ty: Ty<'tcx>,
|
||||
expected_ref: ty::PolyTraitRef<'tcx>,
|
||||
found_ref: ty::PolyTraitRef<'tcx>,
|
||||
type_error: &TypeError<'tcx>)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
let mut err = struct_span_err!(self.tcx.sess, span, E0281,
|
||||
"type mismatch: `{}` implements the trait `{}`, but the trait `{}` is required",
|
||||
expected_ty,
|
||||
expected_ref,
|
||||
found_ref);
|
||||
|
||||
err.span_label(span, &format!("{}", type_error));
|
||||
|
||||
if let Some(sp) = found_span {
|
||||
err.span_label(span, &format!("requires `{}`", found_ref));
|
||||
err.span_label(sp, &format!("implements `{}`", expected_ref));
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
fn report_arg_count_mismatch(&self,
|
||||
span: Span,
|
||||
found_span: Option<Span>,
|
||||
expected: usize,
|
||||
found: usize,
|
||||
is_closure: bool)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
let mut err = struct_span_err!(self.tcx.sess, span, E0593,
|
||||
"{} takes {} argument{} but {} argument{} {} required",
|
||||
if is_closure { "closure" } else { "function" },
|
||||
found,
|
||||
if found == 1 { "" } else { "s" },
|
||||
expected,
|
||||
if expected == 1 { "" } else { "s" },
|
||||
if expected == 1 { "is" } else { "are" });
|
||||
|
||||
err.span_label(span, &format!("expected {} that takes {} argument{}",
|
||||
if is_closure { "closure" } else { "function" },
|
||||
expected,
|
||||
if expected == 1 { "" } else { "s" }));
|
||||
if let Some(span) = found_span {
|
||||
err.span_label(span, &format!("takes {} argument{}",
|
||||
found,
|
||||
if found == 1 { "" } else { "s" }));
|
||||
}
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
@ -117,12 +117,16 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
write!(f, "lifetimes do not intersect")
|
||||
}
|
||||
RegionsInsufficientlyPolymorphic(br, _, _) => {
|
||||
write!(f, "expected bound lifetime parameter {}, \
|
||||
found concrete lifetime", br)
|
||||
write!(f,
|
||||
"expected bound lifetime parameter{}{}, found concrete lifetime",
|
||||
if br.is_named() { " " } else { "" },
|
||||
br)
|
||||
}
|
||||
RegionsOverlyPolymorphic(br, _, _) => {
|
||||
write!(f, "expected concrete lifetime, \
|
||||
found bound lifetime parameter {}", br)
|
||||
write!(f,
|
||||
"expected concrete lifetime, found bound lifetime parameter{}{}",
|
||||
if br.is_named() { " " } else { "" },
|
||||
br)
|
||||
}
|
||||
Sorts(values) => ty::tls::with(|tcx| {
|
||||
report_maybe_different(f, values.expected.sort_string(tcx),
|
||||
|
@ -68,6 +68,15 @@ pub enum BoundRegion {
|
||||
BrEnv,
|
||||
}
|
||||
|
||||
impl BoundRegion {
|
||||
pub fn is_named(&self) -> bool {
|
||||
match *self {
|
||||
BoundRegion::BrNamed(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// When a region changed from late-bound to early-bound when #32330
|
||||
/// was fixed, its `RegionParameterDef` will have one of these
|
||||
/// structures that we can use to give nicer errors.
|
||||
@ -1193,6 +1202,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_closure(&self) -> bool {
|
||||
match self.sty {
|
||||
TyClosure(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_integral(&self) -> bool {
|
||||
match self.sty {
|
||||
TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true,
|
||||
|
25
src/test/ui/mismatched_types/E0281.rs
Normal file
25
src/test/ui/mismatched_types/E0281.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn foo<F: Fn(usize)>(x: F) { }
|
||||
|
||||
fn main() {
|
||||
foo(|y: String| { });
|
||||
//~^ ERROR E0281
|
||||
//~| ERROR E0281
|
||||
//~| NOTE implements
|
||||
//~| NOTE implements
|
||||
//~| NOTE requires
|
||||
//~| NOTE requires
|
||||
//~| NOTE expected usize, found struct `std::string::String`
|
||||
//~| NOTE expected usize, found struct `std::string::String`
|
||||
//~| NOTE required by `foo`
|
||||
//~| NOTE required by `foo`
|
||||
}
|
24
src/test/ui/mismatched_types/E0281.stderr
Normal file
24
src/test/ui/mismatched_types/E0281.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
error[E0281]: type mismatch: `[closure@$DIR/E0281.rs:14:9: 14:24]` implements the trait `std::ops::Fn<(std::string::String,)>`, but the trait `std::ops::Fn<(usize,)>` is required
|
||||
--> $DIR/E0281.rs:14:5
|
||||
|
|
||||
14 | foo(|y: String| { });
|
||||
| ^^^ --------------- implements `std::ops::Fn<(std::string::String,)>`
|
||||
| |
|
||||
| requires `std::ops::Fn<(usize,)>`
|
||||
| expected usize, found struct `std::string::String`
|
||||
|
|
||||
= note: required by `foo`
|
||||
|
||||
error[E0281]: type mismatch: `[closure@$DIR/E0281.rs:14:9: 14:24]` implements the trait `std::ops::FnOnce<(std::string::String,)>`, but the trait `std::ops::FnOnce<(usize,)>` is required
|
||||
--> $DIR/E0281.rs:14:5
|
||||
|
|
||||
14 | foo(|y: String| { });
|
||||
| ^^^ --------------- implements `std::ops::FnOnce<(std::string::String,)>`
|
||||
| |
|
||||
| requires `std::ops::FnOnce<(usize,)>`
|
||||
| expected usize, found struct `std::string::String`
|
||||
|
|
||||
= note: required by `foo`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
15
src/test/ui/mismatched_types/closure-arg-count.rs
Normal file
15
src/test/ui/mismatched_types/closure-arg-count.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
[1, 2, 3].sort_by(|| panic!());
|
||||
[1, 2, 3].sort_by(|tuple| panic!());
|
||||
[1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
|
||||
}
|
59
src/test/ui/mismatched_types/closure-arg-count.stderr
Normal file
59
src/test/ui/mismatched_types/closure-arg-count.stderr
Normal file
@ -0,0 +1,59 @@
|
||||
error[E0593]: closure takes 0 arguments but 2 arguments are required
|
||||
--> $DIR/closure-arg-count.rs:12:15
|
||||
|
|
||||
12 | [1, 2, 3].sort_by(|| panic!());
|
||||
| ^^^^^^^ ----------- takes 0 arguments
|
||||
| |
|
||||
| expected closure that takes 2 arguments
|
||||
|
||||
error[E0593]: closure takes 0 arguments but 2 arguments are required
|
||||
--> $DIR/closure-arg-count.rs:12:15
|
||||
|
|
||||
12 | [1, 2, 3].sort_by(|| panic!());
|
||||
| ^^^^^^^ ----------- takes 0 arguments
|
||||
| |
|
||||
| expected closure that takes 2 arguments
|
||||
|
||||
error[E0593]: closure takes 1 argument but 2 arguments are required
|
||||
--> $DIR/closure-arg-count.rs:13:15
|
||||
|
|
||||
13 | [1, 2, 3].sort_by(|tuple| panic!());
|
||||
| ^^^^^^^ ---------------- takes 1 argument
|
||||
| |
|
||||
| expected closure that takes 2 arguments
|
||||
|
||||
error[E0593]: closure takes 1 argument but 2 arguments are required
|
||||
--> $DIR/closure-arg-count.rs:13:15
|
||||
|
|
||||
13 | [1, 2, 3].sort_by(|tuple| panic!());
|
||||
| ^^^^^^^ ---------------- takes 1 argument
|
||||
| |
|
||||
| expected closure that takes 2 arguments
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-arg-count.rs:14:24
|
||||
|
|
||||
14 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
|
||||
| ^^^^^^^^^^^^^^^ expected &{integer}, found tuple
|
||||
|
|
||||
= note: expected type `&{integer}`
|
||||
found type `(_, _)`
|
||||
|
||||
error[E0593]: closure takes 1 argument but 2 arguments are required
|
||||
--> $DIR/closure-arg-count.rs:14:15
|
||||
|
|
||||
14 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
|
||||
| ^^^^^^^ -------------------------- takes 1 argument
|
||||
| |
|
||||
| expected closure that takes 2 arguments
|
||||
|
||||
error[E0593]: closure takes 1 argument but 2 arguments are required
|
||||
--> $DIR/closure-arg-count.rs:14:15
|
||||
|
|
||||
14 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!());
|
||||
| ^^^^^^^ -------------------------- takes 1 argument
|
||||
| |
|
||||
| expected closure that takes 2 arguments
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -8,9 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn foo<F: Fn()>(x: F) { }
|
||||
trait Foo {}
|
||||
|
||||
impl<T: Fn(&())> Foo for T {}
|
||||
|
||||
fn baz<T: Foo>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
foo(|y| { }); //~ ERROR E0281
|
||||
//~^ ERROR E0281
|
||||
baz(|_| ());
|
||||
}
|
24
src/test/ui/mismatched_types/closure-mismatch.stderr
Normal file
24
src/test/ui/mismatched_types/closure-mismatch.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.rs:18:9: 18:15] as std::ops::FnOnce<(&'r (),)>>::Output == ()`
|
||||
--> $DIR/closure-mismatch.rs:18:5
|
||||
|
|
||||
18 | baz(|_| ());
|
||||
| ^^^ expected bound lifetime parameter, found concrete lifetime
|
||||
|
|
||||
= note: concrete lifetime that was found is lifetime '_#0r
|
||||
= note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
|
||||
= note: required by `baz`
|
||||
|
||||
error[E0281]: type mismatch: `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` implements the trait `std::ops::Fn<(_,)>`, but the trait `for<'r> std::ops::Fn<(&'r (),)>` is required
|
||||
--> $DIR/closure-mismatch.rs:18:5
|
||||
|
|
||||
18 | baz(|_| ());
|
||||
| ^^^ ------ implements `std::ops::Fn<(_,)>`
|
||||
| |
|
||||
| requires `for<'r> std::ops::Fn<(&'r (),)>`
|
||||
| expected concrete lifetime, found bound lifetime parameter
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
|
||||
= note: required by `baz`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -19,9 +19,13 @@ fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
|
||||
fn main() {
|
||||
apply(&3, takes_imm);
|
||||
apply(&3, takes_mut);
|
||||
//~^ ERROR (types differ in mutability)
|
||||
//~^ ERROR type mismatch
|
||||
//~| NOTE types differ in mutability
|
||||
//~| NOTE required by `apply`
|
||||
|
||||
apply(&mut 3, takes_mut);
|
||||
apply(&mut 3, takes_imm);
|
||||
//~^ ERROR (types differ in mutability)
|
||||
//~^ ERROR type mismatch
|
||||
//~| NOTE types differ in mutability
|
||||
//~| NOTE required by `apply`
|
||||
}
|
18
src/test/ui/mismatched_types/fn-variance-1.stderr
Normal file
18
src/test/ui/mismatched_types/fn-variance-1.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0281]: type mismatch: `fn(&mut isize) {takes_mut}` implements the trait `for<'r> std::ops::FnOnce<(&'r mut isize,)>`, but the trait `std::ops::FnOnce<(&{integer},)>` is required
|
||||
--> $DIR/fn-variance-1.rs:21:5
|
||||
|
|
||||
21 | apply(&3, takes_mut);
|
||||
| ^^^^^ types differ in mutability
|
||||
|
|
||||
= note: required by `apply`
|
||||
|
||||
error[E0281]: type mismatch: `fn(&isize) {takes_imm}` implements the trait `for<'r> std::ops::FnOnce<(&'r isize,)>`, but the trait `std::ops::FnOnce<(&mut {integer},)>` is required
|
||||
--> $DIR/fn-variance-1.rs:27:5
|
||||
|
|
||||
27 | apply(&mut 3, takes_imm);
|
||||
| ^^^^^ types differ in mutability
|
||||
|
|
||||
= note: required by `apply`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -18,4 +18,11 @@ fn main() {
|
||||
//~^ ERROR no method named `count`
|
||||
//~| ERROR E0281
|
||||
//~| ERROR E0281
|
||||
//~| NOTE expected &str, found str
|
||||
//~| NOTE expected &str, found str
|
||||
//~| NOTE implements
|
||||
//~| NOTE implements
|
||||
//~| NOTE requires
|
||||
//~| NOTE requires
|
||||
//~| NOTE the method `count` exists but the following trait bounds
|
||||
}
|
28
src/test/ui/mismatched_types/issue-36053-2.stderr
Normal file
28
src/test/ui/mismatched_types/issue-36053-2.stderr
Normal file
@ -0,0 +1,28 @@
|
||||
error: no method named `count` found for type `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]>` in the current scope
|
||||
--> $DIR/issue-36053-2.rs:17:55
|
||||
|
|
||||
17 | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the method `count` exists but the following trait bounds were not satisfied: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>`, `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
|
||||
|
||||
error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` implements the trait `for<'r> std::ops::FnMut<(&'r str,)>`, but the trait `for<'r> std::ops::FnMut<(&'r &str,)>` is required
|
||||
--> $DIR/issue-36053-2.rs:17:32
|
||||
|
|
||||
17 | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^^ -------------- implements `for<'r> std::ops::FnMut<(&'r str,)>`
|
||||
| |
|
||||
| requires `for<'r> std::ops::FnMut<(&'r &str,)>`
|
||||
| expected &str, found str
|
||||
|
||||
error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` implements the trait `for<'r> std::ops::FnOnce<(&'r str,)>`, but the trait `for<'r> std::ops::FnOnce<(&'r &str,)>` is required
|
||||
--> $DIR/issue-36053-2.rs:17:32
|
||||
|
|
||||
17 | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^^ -------------- implements `for<'r> std::ops::FnOnce<(&'r str,)>`
|
||||
| |
|
||||
| requires `for<'r> std::ops::FnOnce<(&'r &str,)>`
|
||||
| expected &str, found str
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -20,8 +20,16 @@ fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
|
||||
|
||||
pub fn main() {
|
||||
let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
|
||||
//~^ NOTE implements
|
||||
//~| NOTE implements
|
||||
let z = call_it(3, f);
|
||||
//~^ ERROR type mismatch
|
||||
//~| ERROR type mismatch
|
||||
//~| NOTE expected isize, found usize
|
||||
//~| NOTE expected isize, found usize
|
||||
//~| NOTE requires
|
||||
//~| NOTE requires
|
||||
//~| NOTE required by `call_it`
|
||||
//~| NOTE required by `call_it`
|
||||
println!("{}", z);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
error[E0281]: type mismatch: `[closure@$DIR/unboxed-closures-vtable-mismatch.rs:22:23: 22:73]` implements the trait `std::ops::FnMut<(usize, isize)>`, but the trait `std::ops::FnMut<(isize, isize)>` is required
|
||||
--> $DIR/unboxed-closures-vtable-mismatch.rs:25:13
|
||||
|
|
||||
22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
|
||||
| -------------------------------------------------- implements `std::ops::FnMut<(usize, isize)>`
|
||||
...
|
||||
25 | let z = call_it(3, f);
|
||||
| ^^^^^^^
|
||||
| |
|
||||
| requires `std::ops::FnMut<(isize, isize)>`
|
||||
| expected isize, found usize
|
||||
|
|
||||
= note: required by `call_it`
|
||||
|
||||
error[E0281]: type mismatch: `[closure@$DIR/unboxed-closures-vtable-mismatch.rs:22:23: 22:73]` implements the trait `std::ops::FnOnce<(usize, isize)>`, but the trait `std::ops::FnOnce<(isize, isize)>` is required
|
||||
--> $DIR/unboxed-closures-vtable-mismatch.rs:25:13
|
||||
|
|
||||
22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
|
||||
| -------------------------------------------------- implements `std::ops::FnOnce<(usize, isize)>`
|
||||
...
|
||||
25 | let z = call_it(3, f);
|
||||
| ^^^^^^^
|
||||
| |
|
||||
| requires `std::ops::FnOnce<(isize, isize)>`
|
||||
| expected isize, found usize
|
||||
|
|
||||
= note: required by `call_it`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user