mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Recover fn
keyword as Fn
trait in bounds
This commit is contained in:
parent
caa64e5b5e
commit
aff403cf68
@ -365,3 +365,6 @@ parse_invalid_identifier_with_leading_number = expected identifier, found number
|
|||||||
|
|
||||||
parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
|
parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
|
||||||
.suggestion = replace `fn` with `impl` here
|
.suggestion = replace `fn` with `impl` here
|
||||||
|
|
||||||
|
parse_expected_fn_path_found_fn_keyword = expected identifier, found keyword `fn`
|
||||||
|
.suggestion = use `Fn` to refer to the trait
|
||||||
|
@ -626,7 +626,7 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
|
|
||||||
// Builds `#[name = val]`.
|
// Builds `#[name = val]`.
|
||||||
//
|
//
|
||||||
// Note: `span` is used for both the identifer and the value.
|
// Note: `span` is used for both the identifier and the value.
|
||||||
pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute {
|
pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute {
|
||||||
let g = &self.sess.parse_sess.attr_id_generator;
|
let g = &self.sess.parse_sess.attr_id_generator;
|
||||||
attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span)
|
attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span)
|
||||||
|
@ -851,7 +851,7 @@ impl Cursor<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Eats the identifier. Note: succeeds on `_`, which isn't a valid
|
// Eats the identifier. Note: succeeds on `_`, which isn't a valid
|
||||||
// identifer.
|
// identifier.
|
||||||
fn eat_identifier(&mut self) {
|
fn eat_identifier(&mut self) {
|
||||||
if !is_id_start(self.first()) {
|
if !is_id_start(self.first()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1229,3 +1229,11 @@ pub(crate) struct FnTypoWithImpl {
|
|||||||
#[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
|
#[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
|
||||||
pub fn_span: Span,
|
pub fn_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_expected_fn_path_found_fn_keyword)]
|
||||||
|
pub(crate) struct ExpectedFnPathFoundFnKeyword {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
|
||||||
|
pub fn_token_span: Span,
|
||||||
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use super::{Parser, PathStyle, TokenType};
|
use super::{Parser, PathStyle, TokenType};
|
||||||
|
|
||||||
use crate::errors::{FnPtrWithGenerics, FnPtrWithGenericsSugg};
|
use crate::errors::{ExpectedFnPathFoundFnKeyword, FnPtrWithGenerics, FnPtrWithGenericsSugg};
|
||||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||||
|
|
||||||
|
use ast::DUMMY_NODE_ID;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||||
use rustc_ast::util::case::Case;
|
use rustc_ast::util::case::Case;
|
||||||
@ -12,7 +13,9 @@ use rustc_ast::{
|
|||||||
};
|
};
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
|
use rustc_span::Symbol;
|
||||||
|
use thin_vec::thin_vec;
|
||||||
|
|
||||||
/// Any `?` or `~const` modifiers that appear at the start of a bound.
|
/// Any `?` or `~const` modifiers that appear at the start of a bound.
|
||||||
struct BoundModifiers {
|
struct BoundModifiers {
|
||||||
@ -912,7 +915,14 @@ impl<'a> Parser<'a> {
|
|||||||
modifiers: BoundModifiers,
|
modifiers: BoundModifiers,
|
||||||
) -> PResult<'a, GenericBound> {
|
) -> PResult<'a, GenericBound> {
|
||||||
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||||
let path = self.parse_path(PathStyle::Type)?;
|
let path = if self.token.is_keyword(kw::Fn)
|
||||||
|
&& self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis))
|
||||||
|
&& let Some(path) = self.recover_path_from_fn()
|
||||||
|
{
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
self.parse_path(PathStyle::Type)?
|
||||||
|
};
|
||||||
if has_parens {
|
if has_parens {
|
||||||
if self.token.is_like_plus() {
|
if self.token.is_like_plus() {
|
||||||
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
||||||
@ -941,6 +951,38 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(GenericBound::Trait(poly_trait, modifier))
|
Ok(GenericBound::Trait(poly_trait, modifier))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// recovers a `Fn(..)` parenthesized-style path from `fn(..)`
|
||||||
|
fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
|
||||||
|
let fn_token_span = self.token.span;
|
||||||
|
self.bump();
|
||||||
|
let args_lo = self.token.span;
|
||||||
|
let snapshot = self.create_snapshot_for_diagnostic();
|
||||||
|
match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
|
||||||
|
Ok(decl) => {
|
||||||
|
self.sess.emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
|
||||||
|
Some(ast::Path {
|
||||||
|
span: fn_token_span.to(self.prev_token.span),
|
||||||
|
segments: thin_vec![ast::PathSegment {
|
||||||
|
ident: Ident::new(Symbol::intern("Fn"), fn_token_span),
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
|
||||||
|
span: args_lo.to(self.prev_token.span),
|
||||||
|
inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
|
||||||
|
inputs_span: args_lo.until(decl.output.span()),
|
||||||
|
output: decl.output.clone(),
|
||||||
|
}))),
|
||||||
|
}],
|
||||||
|
tokens: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(diag) => {
|
||||||
|
diag.cancel();
|
||||||
|
self.restore_snapshot(snapshot);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Optionally parses `for<$generic_params>`.
|
/// Optionally parses `for<$generic_params>`.
|
||||||
pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
|
pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
|
||||||
if self.eat_keyword(kw::For) {
|
if self.eat_keyword(kw::For) {
|
||||||
|
@ -4,21 +4,13 @@ fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
|||||||
//~^ ERROR expected identifier, found keyword `fn`
|
//~^ ERROR expected identifier, found keyword `fn`
|
||||||
//~| ERROR expected identifier, found keyword `fn`
|
//~| ERROR expected identifier, found keyword `fn`
|
||||||
//~| ERROR expected identifier, found keyword `fn`
|
//~| ERROR expected identifier, found keyword `fn`
|
||||||
//~| ERROR cannot find trait `r#fn` in this scope
|
//~| HELP use `Fn` to refer to the trait
|
||||||
//~| ERROR cannot find trait `r#fn` in this scope
|
//~| HELP use `Fn` to refer to the trait
|
||||||
//~| ERROR cannot find trait `r#fn` in this scope
|
//~| HELP use `Fn` to refer to the trait
|
||||||
//~| HELP a trait with a similar name exists
|
|
||||||
//~| HELP a trait with a similar name exists
|
|
||||||
//~| HELP a trait with a similar name exists
|
|
||||||
//~| HELP escape `fn` to use it as an identifier
|
|
||||||
//~| HELP escape `fn` to use it as an identifier
|
|
||||||
//~| HELP escape `fn` to use it as an identifier
|
|
||||||
where
|
where
|
||||||
G: fn(),
|
G: fn(),
|
||||||
//~^ ERROR expected identifier, found keyword `fn`
|
//~^ ERROR expected identifier, found keyword `fn`
|
||||||
//~| ERROR cannot find trait `r#fn` in this scope
|
//~| HELP use `Fn` to refer to the trait
|
||||||
//~| HELP a trait with a similar name exists
|
|
||||||
//~| HELP escape `fn` to use it as an identifier
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
|
@ -2,48 +2,48 @@ error: expected identifier, found keyword `fn`
|
|||||||
--> $DIR/kw-in-trait-bounds.rs:3:10
|
--> $DIR/kw-in-trait-bounds.rs:3:10
|
||||||
|
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||||
| ^^ expected identifier, found keyword
|
| ^^
|
||||||
|
|
|
|
||||||
help: escape `fn` to use it as an identifier
|
help: use `Fn` to refer to the trait
|
||||||
|
|
|
|
||||||
LL | fn _f<F: r#fn(), G>(_: impl fn(), _: &dyn fn())
|
LL | fn _f<F: Fn(), G>(_: impl fn(), _: &dyn fn())
|
||||||
| ++
|
| ~~
|
||||||
|
|
||||||
error: expected identifier, found keyword `fn`
|
error: expected identifier, found keyword `fn`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:3:27
|
--> $DIR/kw-in-trait-bounds.rs:3:27
|
||||||
|
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||||
| ^^ expected identifier, found keyword
|
| ^^
|
||||||
|
|
|
|
||||||
help: escape `fn` to use it as an identifier
|
help: use `Fn` to refer to the trait
|
||||||
|
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl r#fn(), _: &dyn fn())
|
LL | fn _f<F: fn(), G>(_: impl Fn(), _: &dyn fn())
|
||||||
| ++
|
| ~~
|
||||||
|
|
||||||
error: expected identifier, found keyword `fn`
|
error: expected identifier, found keyword `fn`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:3:41
|
--> $DIR/kw-in-trait-bounds.rs:3:41
|
||||||
|
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||||
| ^^ expected identifier, found keyword
|
| ^^
|
||||||
|
|
|
|
||||||
help: escape `fn` to use it as an identifier
|
help: use `Fn` to refer to the trait
|
||||||
|
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn r#fn())
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn Fn())
|
||||||
| ++
|
| ~~
|
||||||
|
|
||||||
error: expected identifier, found keyword `fn`
|
error: expected identifier, found keyword `fn`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:17:4
|
--> $DIR/kw-in-trait-bounds.rs:11:4
|
||||||
|
|
|
|
||||||
LL | G: fn(),
|
LL | G: fn(),
|
||||||
| ^^ expected identifier, found keyword
|
| ^^
|
||||||
|
|
|
|
||||||
help: escape `fn` to use it as an identifier
|
help: use `Fn` to refer to the trait
|
||||||
|
|
|
|
||||||
LL | G: r#fn(),
|
LL | G: Fn(),
|
||||||
| ++
|
| ~~
|
||||||
|
|
||||||
error: expected identifier, found keyword `struct`
|
error: expected identifier, found keyword `struct`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:24:10
|
--> $DIR/kw-in-trait-bounds.rs:16:10
|
||||||
|
|
|
|
||||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
| ^^^^^^ expected identifier, found keyword
|
| ^^^^^^ expected identifier, found keyword
|
||||||
@ -54,7 +54,7 @@ LL | fn _g<A: r#struct, B>(_: impl struct, _: &dyn struct)
|
|||||||
| ++
|
| ++
|
||||||
|
|
||||||
error: expected identifier, found keyword `struct`
|
error: expected identifier, found keyword `struct`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:24:29
|
--> $DIR/kw-in-trait-bounds.rs:16:29
|
||||||
|
|
|
|
||||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
| ^^^^^^ expected identifier, found keyword
|
| ^^^^^^ expected identifier, found keyword
|
||||||
@ -65,7 +65,7 @@ LL | fn _g<A: struct, B>(_: impl r#struct, _: &dyn struct)
|
|||||||
| ++
|
| ++
|
||||||
|
|
||||||
error: expected identifier, found keyword `struct`
|
error: expected identifier, found keyword `struct`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:24:45
|
--> $DIR/kw-in-trait-bounds.rs:16:45
|
||||||
|
|
|
|
||||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
| ^^^^^^ expected identifier, found keyword
|
| ^^^^^^ expected identifier, found keyword
|
||||||
@ -76,7 +76,7 @@ LL | fn _g<A: struct, B>(_: impl struct, _: &dyn r#struct)
|
|||||||
| ++
|
| ++
|
||||||
|
|
||||||
error: expected identifier, found keyword `struct`
|
error: expected identifier, found keyword `struct`
|
||||||
--> $DIR/kw-in-trait-bounds.rs:38:8
|
--> $DIR/kw-in-trait-bounds.rs:30:8
|
||||||
|
|
|
|
||||||
LL | B: struct,
|
LL | B: struct,
|
||||||
| ^^^^^^ expected identifier, found keyword
|
| ^^^^^^ expected identifier, found keyword
|
||||||
@ -86,44 +86,8 @@ help: escape `struct` to use it as an identifier
|
|||||||
LL | B: r#struct,
|
LL | B: r#struct,
|
||||||
| ++
|
| ++
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#fn` in this scope
|
|
||||||
--> $DIR/kw-in-trait-bounds.rs:3:10
|
|
||||||
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
|
||||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
|
||||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: similarly named trait `Fn` defined here
|
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#fn` in this scope
|
|
||||||
--> $DIR/kw-in-trait-bounds.rs:17:4
|
|
||||||
|
|
|
||||||
LL | G: fn(),
|
|
||||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
|
||||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: similarly named trait `Fn` defined here
|
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#fn` in this scope
|
|
||||||
--> $DIR/kw-in-trait-bounds.rs:3:27
|
|
||||||
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
|
||||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
|
||||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: similarly named trait `Fn` defined here
|
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#fn` in this scope
|
|
||||||
--> $DIR/kw-in-trait-bounds.rs:3:41
|
|
||||||
|
|
|
||||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
|
||||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
|
||||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: similarly named trait `Fn` defined here
|
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#struct` in this scope
|
error[E0405]: cannot find trait `r#struct` in this scope
|
||||||
--> $DIR/kw-in-trait-bounds.rs:24:10
|
--> $DIR/kw-in-trait-bounds.rs:16:10
|
||||||
|
|
|
|
||||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||||
@ -132,7 +96,7 @@ LL | trait Struct {}
|
|||||||
| ------------ similarly named trait `Struct` defined here
|
| ------------ similarly named trait `Struct` defined here
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#struct` in this scope
|
error[E0405]: cannot find trait `r#struct` in this scope
|
||||||
--> $DIR/kw-in-trait-bounds.rs:38:8
|
--> $DIR/kw-in-trait-bounds.rs:30:8
|
||||||
|
|
|
|
||||||
LL | B: struct,
|
LL | B: struct,
|
||||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||||
@ -141,7 +105,7 @@ LL | trait Struct {}
|
|||||||
| ------------ similarly named trait `Struct` defined here
|
| ------------ similarly named trait `Struct` defined here
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#struct` in this scope
|
error[E0405]: cannot find trait `r#struct` in this scope
|
||||||
--> $DIR/kw-in-trait-bounds.rs:24:29
|
--> $DIR/kw-in-trait-bounds.rs:16:29
|
||||||
|
|
|
|
||||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||||
@ -150,7 +114,7 @@ LL | trait Struct {}
|
|||||||
| ------------ similarly named trait `Struct` defined here
|
| ------------ similarly named trait `Struct` defined here
|
||||||
|
|
||||||
error[E0405]: cannot find trait `r#struct` in this scope
|
error[E0405]: cannot find trait `r#struct` in this scope
|
||||||
--> $DIR/kw-in-trait-bounds.rs:24:45
|
--> $DIR/kw-in-trait-bounds.rs:16:45
|
||||||
|
|
|
|
||||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||||
@ -158,6 +122,6 @@ LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
|||||||
LL | trait Struct {}
|
LL | trait Struct {}
|
||||||
| ------------ similarly named trait `Struct` defined here
|
| ------------ similarly named trait `Struct` defined here
|
||||||
|
|
||||||
error: aborting due to 16 previous errors
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0405`.
|
For more information about this error, try `rustc --explain E0405`.
|
||||||
|
12
src/test/ui/parser/recover-fn-trait-from-fn-kw.rs
Normal file
12
src/test/ui/parser/recover-fn-trait-from-fn-kw.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
fn foo(_: impl fn() -> i32) {}
|
||||||
|
//~^ ERROR expected identifier, found keyword `fn`
|
||||||
|
|
||||||
|
fn foo2<T: fn(i32)>(_: T) {}
|
||||||
|
//~^ ERROR expected identifier, found keyword `fn`
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(|| ());
|
||||||
|
//~^ mismatched types
|
||||||
|
foo2(|_: ()| {});
|
||||||
|
//~^ type mismatch in closure arguments
|
||||||
|
}
|
48
src/test/ui/parser/recover-fn-trait-from-fn-kw.stderr
Normal file
48
src/test/ui/parser/recover-fn-trait-from-fn-kw.stderr
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
error: expected identifier, found keyword `fn`
|
||||||
|
--> $DIR/recover-fn-trait-from-fn-kw.rs:1:16
|
||||||
|
|
|
||||||
|
LL | fn foo(_: impl fn() -> i32) {}
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
help: use `Fn` to refer to the trait
|
||||||
|
|
|
||||||
|
LL | fn foo(_: impl Fn() -> i32) {}
|
||||||
|
| ~~
|
||||||
|
|
||||||
|
error: expected identifier, found keyword `fn`
|
||||||
|
--> $DIR/recover-fn-trait-from-fn-kw.rs:4:12
|
||||||
|
|
|
||||||
|
LL | fn foo2<T: fn(i32)>(_: T) {}
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
help: use `Fn` to refer to the trait
|
||||||
|
|
|
||||||
|
LL | fn foo2<T: Fn(i32)>(_: T) {}
|
||||||
|
| ~~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/recover-fn-trait-from-fn-kw.rs:8:12
|
||||||
|
|
|
||||||
|
LL | foo(|| ());
|
||||||
|
| ^^ expected `i32`, found `()`
|
||||||
|
|
||||||
|
error[E0631]: type mismatch in closure arguments
|
||||||
|
--> $DIR/recover-fn-trait-from-fn-kw.rs:10:5
|
||||||
|
|
|
||||||
|
LL | foo2(|_: ()| {});
|
||||||
|
| ^^^^ ------- found signature defined here
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected closure signature `fn(i32) -> _`
|
||||||
|
found closure signature `fn(()) -> _`
|
||||||
|
note: required by a bound in `foo2`
|
||||||
|
--> $DIR/recover-fn-trait-from-fn-kw.rs:4:12
|
||||||
|
|
|
||||||
|
LL | fn foo2<T: fn(i32)>(_: T) {}
|
||||||
|
| ^^^^^^^ required by this bound in `foo2`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0308, E0631.
|
||||||
|
For more information about an error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user