Gracefully handle confusing -> with : in function return type
This commit is contained in:
parent
5404deeb64
commit
3548be94c0
18 changed files with 205 additions and 79 deletions
|
@ -1,5 +1,5 @@
|
||||||
use super::pat::{GateOr, PARAM_EXPECTED};
|
use super::pat::{GateOr, PARAM_EXPECTED};
|
||||||
use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath};
|
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||||
use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType};
|
use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType};
|
||||||
use super::{SemiColonMode, SeqSep, TokenExpectType};
|
use super::{SemiColonMode, SeqSep, TokenExpectType};
|
||||||
use crate::maybe_recover_from_interpolated_ty_qpath;
|
use crate::maybe_recover_from_interpolated_ty_qpath;
|
||||||
|
@ -1647,7 +1647,8 @@ impl<'a> Parser<'a> {
|
||||||
self.expect_or()?;
|
self.expect_or()?;
|
||||||
args
|
args
|
||||||
};
|
};
|
||||||
let output = self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverFatArrow::Yes)?;
|
let output =
|
||||||
|
self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes)?;
|
||||||
|
|
||||||
Ok(P(FnDecl { inputs, output }))
|
Ok(P(FnDecl { inputs, output }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// Parse type with mandatory colon and (possibly empty) bounds,
|
// Parse type with mandatory colon and (possibly empty) bounds,
|
||||||
// or with mandatory equality sign and the second type.
|
// or with mandatory equality sign and the second type.
|
||||||
let ty = self.parse_ty()?;
|
let ty = self.parse_ty_for_where_clause()?;
|
||||||
if self.eat(&token::Colon) {
|
if self.eat(&token::Colon) {
|
||||||
let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
|
let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
|
||||||
Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
|
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
|
||||||
use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath};
|
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||||
use super::{FollowedByType, Parser, PathStyle};
|
use super::{FollowedByType, Parser, PathStyle};
|
||||||
|
|
||||||
use crate::maybe_whole;
|
use crate::maybe_whole;
|
||||||
|
@ -1514,7 +1514,7 @@ impl<'a> Parser<'a> {
|
||||||
let header = self.parse_fn_front_matter()?; // `const ... fn`
|
let header = self.parse_fn_front_matter()?; // `const ... fn`
|
||||||
let ident = self.parse_ident()?; // `foo`
|
let ident = self.parse_ident()?; // `foo`
|
||||||
let mut generics = self.parse_generics()?; // `<'a, T, ...>`
|
let mut generics = self.parse_generics()?; // `<'a, T, ...>`
|
||||||
let decl = self.parse_fn_decl(req_name, AllowPlus::Yes)?; // `(p: u8, ...)`
|
let decl = self.parse_fn_decl(req_name, AllowPlus::Yes, RecoverReturnSign::Yes)?; // `(p: u8, ...)`
|
||||||
generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
|
generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
|
||||||
|
|
||||||
let mut sig_hi = self.prev_token.span;
|
let mut sig_hi = self.prev_token.span;
|
||||||
|
@ -1645,10 +1645,11 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
req_name: ReqName,
|
req_name: ReqName,
|
||||||
ret_allow_plus: AllowPlus,
|
ret_allow_plus: AllowPlus,
|
||||||
|
recover_return_sign: RecoverReturnSign,
|
||||||
) -> PResult<'a, P<FnDecl>> {
|
) -> PResult<'a, P<FnDecl>> {
|
||||||
Ok(P(FnDecl {
|
Ok(P(FnDecl {
|
||||||
inputs: self.parse_fn_params(req_name)?,
|
inputs: self.parse_fn_params(req_name)?,
|
||||||
output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, RecoverFatArrow::Yes)?,
|
output: self.parse_ret_ty(ret_allow_plus, RecoverQPath::Yes, recover_return_sign)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath};
|
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||||
use super::{Parser, TokenType};
|
use super::{Parser, TokenType};
|
||||||
use crate::maybe_whole;
|
use crate::maybe_whole;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
@ -232,7 +232,7 @@ impl<'a> Parser<'a> {
|
||||||
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
|
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
|
||||||
let span = ident.span.to(self.prev_token.span);
|
let span = ident.span.to(self.prev_token.span);
|
||||||
let output =
|
let output =
|
||||||
self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverFatArrow::No)?;
|
self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?;
|
||||||
ParenthesizedArgs { inputs, output, span }.into()
|
ParenthesizedArgs { inputs, output, span }.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,12 +43,23 @@ pub(super) enum RecoverQPath {
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub(super) enum RecoverFatArrow {
|
pub(super) enum RecoverReturnSign {
|
||||||
Yes,
|
Yes,
|
||||||
|
OnlyFatArrow,
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RecoverReturnSign {
|
||||||
|
fn can_recover(self, token: &TokenKind) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Yes => matches!(token, token::FatArrow | token::Colon),
|
||||||
|
Self::OnlyFatArrow => matches!(token, token::FatArrow),
|
||||||
|
Self::No => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Is `...` (`CVarArgs`) legal at this level of type parsing?
|
// Is `...` (`CVarArgs`) legal at this level of type parsing?
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum AllowCVariadic {
|
enum AllowCVariadic {
|
||||||
|
@ -68,14 +79,24 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
/// Parses a type.
|
/// Parses a type.
|
||||||
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::No)
|
self.parse_ty_common(
|
||||||
|
AllowPlus::Yes,
|
||||||
|
RecoverQPath::Yes,
|
||||||
|
AllowCVariadic::No,
|
||||||
|
RecoverReturnSign::Yes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a type suitable for a function or function pointer parameter.
|
/// Parse a type suitable for a function or function pointer parameter.
|
||||||
/// The difference from `parse_ty` is that this version allows `...`
|
/// The difference from `parse_ty` is that this version allows `...`
|
||||||
/// (`CVarArgs`) at the top level of the type.
|
/// (`CVarArgs`) at the top level of the type.
|
||||||
pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
|
pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(AllowPlus::Yes, RecoverQPath::Yes, AllowCVariadic::Yes)
|
self.parse_ty_common(
|
||||||
|
AllowPlus::Yes,
|
||||||
|
RecoverQPath::Yes,
|
||||||
|
AllowCVariadic::Yes,
|
||||||
|
RecoverReturnSign::Yes,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a type in restricted contexts where `+` is not permitted.
|
/// Parses a type in restricted contexts where `+` is not permitted.
|
||||||
|
@ -85,7 +106,22 @@ impl<'a> Parser<'a> {
|
||||||
/// Example 2: `value1 as TYPE + value2`
|
/// Example 2: `value1 as TYPE + value2`
|
||||||
/// `+` is prohibited to avoid interactions with expression grammar.
|
/// `+` is prohibited to avoid interactions with expression grammar.
|
||||||
pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
pub(super) fn parse_ty_no_plus(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
self.parse_ty_common(AllowPlus::No, RecoverQPath::Yes, AllowCVariadic::No)
|
self.parse_ty_common(
|
||||||
|
AllowPlus::No,
|
||||||
|
RecoverQPath::Yes,
|
||||||
|
AllowCVariadic::No,
|
||||||
|
RecoverReturnSign::Yes,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
|
||||||
|
pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
|
||||||
|
self.parse_ty_common(
|
||||||
|
AllowPlus::Yes,
|
||||||
|
RecoverQPath::Yes,
|
||||||
|
AllowCVariadic::Yes,
|
||||||
|
RecoverReturnSign::OnlyFatArrow,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an optional return type `[ -> TY ]` in a function declaration.
|
/// Parses an optional return type `[ -> TY ]` in a function declaration.
|
||||||
|
@ -93,13 +129,18 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
allow_plus: AllowPlus,
|
allow_plus: AllowPlus,
|
||||||
recover_qpath: RecoverQPath,
|
recover_qpath: RecoverQPath,
|
||||||
recover_fat_arrow: RecoverFatArrow,
|
recover_return_sign: RecoverReturnSign,
|
||||||
) -> PResult<'a, FnRetTy> {
|
) -> PResult<'a, FnRetTy> {
|
||||||
Ok(if self.eat(&token::RArrow) {
|
Ok(if self.eat(&token::RArrow) {
|
||||||
// FIXME(Centril): Can we unconditionally `allow_plus`?
|
// FIXME(Centril): Can we unconditionally `allow_plus`?
|
||||||
let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?;
|
let ty = self.parse_ty_common(
|
||||||
|
allow_plus,
|
||||||
|
recover_qpath,
|
||||||
|
AllowCVariadic::No,
|
||||||
|
recover_return_sign,
|
||||||
|
)?;
|
||||||
FnRetTy::Ty(ty)
|
FnRetTy::Ty(ty)
|
||||||
} else if recover_fat_arrow == RecoverFatArrow::Yes && self.token == token::FatArrow {
|
} else if recover_return_sign.can_recover(&self.token.kind) {
|
||||||
// Don't `eat` to prevent `=>` from being added as an expected token which isn't
|
// Don't `eat` to prevent `=>` from being added as an expected token which isn't
|
||||||
// actually expected and could only confuse users
|
// actually expected and could only confuse users
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -111,7 +152,12 @@ impl<'a> Parser<'a> {
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?;
|
let ty = self.parse_ty_common(
|
||||||
|
allow_plus,
|
||||||
|
recover_qpath,
|
||||||
|
AllowCVariadic::No,
|
||||||
|
recover_return_sign,
|
||||||
|
)?;
|
||||||
FnRetTy::Ty(ty)
|
FnRetTy::Ty(ty)
|
||||||
} else {
|
} else {
|
||||||
FnRetTy::Default(self.token.span.shrink_to_lo())
|
FnRetTy::Default(self.token.span.shrink_to_lo())
|
||||||
|
@ -123,6 +169,7 @@ impl<'a> Parser<'a> {
|
||||||
allow_plus: AllowPlus,
|
allow_plus: AllowPlus,
|
||||||
recover_qpath: RecoverQPath,
|
recover_qpath: RecoverQPath,
|
||||||
allow_c_variadic: AllowCVariadic,
|
allow_c_variadic: AllowCVariadic,
|
||||||
|
recover_return_sign: RecoverReturnSign,
|
||||||
) -> PResult<'a, P<Ty>> {
|
) -> PResult<'a, P<Ty>> {
|
||||||
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
|
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
|
||||||
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
|
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
|
||||||
|
@ -150,14 +197,14 @@ impl<'a> Parser<'a> {
|
||||||
TyKind::Infer
|
TyKind::Infer
|
||||||
} else if self.check_fn_front_matter() {
|
} else if self.check_fn_front_matter() {
|
||||||
// Function pointer type
|
// Function pointer type
|
||||||
self.parse_ty_bare_fn(lo, Vec::new())?
|
self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)?
|
||||||
} else if self.check_keyword(kw::For) {
|
} else if self.check_keyword(kw::For) {
|
||||||
// Function pointer type or bound list (trait object type) starting with a poly-trait.
|
// Function pointer type or bound list (trait object type) starting with a poly-trait.
|
||||||
// `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
|
// `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
|
||||||
// `for<'lt> Trait1<'lt> + Trait2 + 'a`
|
// `for<'lt> Trait1<'lt> + Trait2 + 'a`
|
||||||
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||||
if self.check_fn_front_matter() {
|
if self.check_fn_front_matter() {
|
||||||
self.parse_ty_bare_fn(lo, lifetime_defs)?
|
self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)?
|
||||||
} else {
|
} else {
|
||||||
let path = self.parse_path(PathStyle::Type)?;
|
let path = self.parse_path(PathStyle::Type)?;
|
||||||
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
|
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
|
||||||
|
@ -359,9 +406,14 @@ impl<'a> Parser<'a> {
|
||||||
/// Function Style ABI Parameter types
|
/// Function Style ABI Parameter types
|
||||||
/// ```
|
/// ```
|
||||||
/// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
|
/// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
|
||||||
fn parse_ty_bare_fn(&mut self, lo: Span, params: Vec<GenericParam>) -> PResult<'a, TyKind> {
|
fn parse_ty_bare_fn(
|
||||||
|
&mut self,
|
||||||
|
lo: Span,
|
||||||
|
params: Vec<GenericParam>,
|
||||||
|
recover_return_sign: RecoverReturnSign,
|
||||||
|
) -> PResult<'a, TyKind> {
|
||||||
let ast::FnHeader { ext, unsafety, constness, asyncness } = self.parse_fn_front_matter()?;
|
let ast::FnHeader { ext, unsafety, constness, asyncness } = self.parse_fn_front_matter()?;
|
||||||
let decl = self.parse_fn_decl(|_| false, AllowPlus::No)?;
|
let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
|
||||||
let whole_span = lo.to(self.prev_token.span);
|
let whole_span = lo.to(self.prev_token.span);
|
||||||
if let ast::Const::Yes(span) = constness {
|
if let ast::Const::Yes(span) = constness {
|
||||||
self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
|
self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
// run-rustfix
|
|
||||||
#![allow(unused)]
|
|
||||||
fn a() -> usize { 0 }
|
|
||||||
//~^ ERROR return types are denoted using `->`
|
|
||||||
|
|
||||||
fn bar(_: u32) {}
|
|
||||||
|
|
||||||
fn baz() -> *const dyn Fn(u32) { unimplemented!() }
|
|
||||||
|
|
||||||
fn foo() {
|
|
||||||
match () {
|
|
||||||
_ if baz() == &bar as &dyn Fn(u32) => (),
|
|
||||||
() => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
error: return types are denoted using `->`
|
|
||||||
--> $DIR/fn-fat-arrow-return.rs:3:8
|
|
||||||
|
|
|
||||||
LL | fn a() => usize { 0 }
|
|
||||||
| ^^ help: use `->` instead
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
fn a() => impl Fn() => bool {
|
|
||||||
//~^ ERROR return types are denoted using `->`
|
|
||||||
//~| ERROR expected `;` or `{`, found `=>`
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let foo = |a: bool| => bool { a };
|
|
||||||
dbg!(foo(false));
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
error: return types are denoted using `->`
|
|
||||||
--> $DIR/fn-fat-arrow-return2.rs:1:8
|
|
||||||
|
|
|
||||||
LL | fn a() => impl Fn() => bool {
|
|
||||||
| ^^ help: use `->` instead
|
|
||||||
|
|
||||||
error: expected `;` or `{`, found `=>`
|
|
||||||
--> $DIR/fn-fat-arrow-return2.rs:1:21
|
|
||||||
|
|
|
||||||
LL | fn a() => impl Fn() => bool {
|
|
||||||
| ^^ expected `;` or `{`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
28
src/test/ui/fn/fn-recover-return-sign.fixed
Normal file
28
src/test/ui/fn/fn-recover-return-sign.fixed
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// run-rustfix
|
||||||
|
#![allow(unused)]
|
||||||
|
fn a() -> usize { 0 }
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
|
||||||
|
fn b()-> usize { 0 }
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
|
||||||
|
fn bar(_: u32) {}
|
||||||
|
|
||||||
|
fn baz() -> *const dyn Fn(u32) { unimplemented!() }
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
match () {
|
||||||
|
_ if baz() == &bar as &dyn Fn(u32) => (),
|
||||||
|
() => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let foo = |a: bool| -> bool { a };
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
dbg!(foo(false));
|
||||||
|
|
||||||
|
let bar = |a: bool|-> bool { a };
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
dbg!(bar(false));
|
||||||
|
}
|
|
@ -3,6 +3,9 @@
|
||||||
fn a() => usize { 0 }
|
fn a() => usize { 0 }
|
||||||
//~^ ERROR return types are denoted using `->`
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
|
||||||
|
fn b(): usize { 0 }
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
|
||||||
fn bar(_: u32) {}
|
fn bar(_: u32) {}
|
||||||
|
|
||||||
fn baz() -> *const dyn Fn(u32) { unimplemented!() }
|
fn baz() -> *const dyn Fn(u32) { unimplemented!() }
|
||||||
|
@ -15,4 +18,11 @@ fn foo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let foo = |a: bool| => bool { a };
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
dbg!(foo(false));
|
||||||
|
|
||||||
|
let bar = |a: bool|: bool { a };
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
dbg!(bar(false));
|
||||||
}
|
}
|
26
src/test/ui/fn/fn-recover-return-sign.stderr
Normal file
26
src/test/ui/fn/fn-recover-return-sign.stderr
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
error: return types are denoted using `->`
|
||||||
|
--> $DIR/fn-recover-return-sign.rs:3:8
|
||||||
|
|
|
||||||
|
LL | fn a() => usize { 0 }
|
||||||
|
| ^^ help: use `->` instead
|
||||||
|
|
||||||
|
error: return types are denoted using `->`
|
||||||
|
--> $DIR/fn-recover-return-sign.rs:6:7
|
||||||
|
|
|
||||||
|
LL | fn b(): usize { 0 }
|
||||||
|
| ^ help: use `->` instead
|
||||||
|
|
||||||
|
error: return types are denoted using `->`
|
||||||
|
--> $DIR/fn-recover-return-sign.rs:21:25
|
||||||
|
|
|
||||||
|
LL | let foo = |a: bool| => bool { a };
|
||||||
|
| ^^ help: use `->` instead
|
||||||
|
|
||||||
|
error: return types are denoted using `->`
|
||||||
|
--> $DIR/fn-recover-return-sign.rs:25:24
|
||||||
|
|
|
||||||
|
LL | let bar = |a: bool|: bool { a };
|
||||||
|
| ^ help: use `->` instead
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
8
src/test/ui/fn/fn-recover-return-sign2.rs
Normal file
8
src/test/ui/fn/fn-recover-return-sign2.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Separate test file because `Fn() => bool` isn't getting fixed and rustfix complained that
|
||||||
|
// even though a fix was applied the code was still incorrect
|
||||||
|
|
||||||
|
fn foo() => impl Fn() => bool {
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
//~| ERROR expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>`
|
||||||
|
unimplemented!()
|
||||||
|
}
|
14
src/test/ui/fn/fn-recover-return-sign2.stderr
Normal file
14
src/test/ui/fn/fn-recover-return-sign2.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error: return types are denoted using `->`
|
||||||
|
--> $DIR/fn-recover-return-sign2.rs:4:10
|
||||||
|
|
|
||||||
|
LL | fn foo() => impl Fn() => bool {
|
||||||
|
| ^^ help: use `->` instead
|
||||||
|
|
||||||
|
error: expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>`
|
||||||
|
--> $DIR/fn-recover-return-sign2.rs:4:23
|
||||||
|
|
|
||||||
|
LL | fn foo() => impl Fn() => bool {
|
||||||
|
| ^^ expected one of `+`, `->`, `::`, `;`, `where`, or `{`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
fn foo(x: i32): i32 { //~ ERROR expected one of `->`, `;`, `where`, or `{`, found `:`
|
fn foo(x: i32): i32 {
|
||||||
|
//~^ ERROR return types are denoted using `->`
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: expected one of `->`, `;`, `where`, or `{`, found `:`
|
error: return types are denoted using `->`
|
||||||
--> $DIR/fn-colon-return-type.rs:1:15
|
--> $DIR/fn-colon-return-type.rs:1:15
|
||||||
|
|
|
|
||||||
LL | fn foo(x: i32): i32 {
|
LL | fn foo(x: i32): i32 {
|
||||||
| ^ expected one of `->`, `;`, `where`, or `{`
|
| ^ help: use `->` instead
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
fn f(a: isize, b: isize) : lt(a, b) { }
|
fn f(a: isize, b: isize) : lt(a, b) { }
|
||||||
//~^ ERROR expected one of `->`, `;`, `where`, or `{`, found `:`
|
//~^ ERROR return types are denoted using `->`
|
||||||
|
//~| ERROR expected type, found function `lt` [E0573]
|
||||||
|
//~| ERROR expected type, found local variable `a` [E0573]
|
||||||
|
//~| ERROR expected type, found local variable `b` [E0573]
|
||||||
|
|
||||||
fn lt(a: isize, b: isize) { }
|
fn lt(a: isize, b: isize) { }
|
||||||
|
|
||||||
fn main() { let a: isize = 10; let b: isize = 23; check (lt(a, b)); f(a, b); }
|
fn main() {
|
||||||
|
let a: isize = 10;
|
||||||
|
let b: isize = 23;
|
||||||
|
check (lt(a, b));
|
||||||
|
//~^ ERROR cannot find function `check` in this scope [E0425]
|
||||||
|
f(a, b);
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,34 @@
|
||||||
error: expected one of `->`, `;`, `where`, or `{`, found `:`
|
error: return types are denoted using `->`
|
||||||
--> $DIR/not-a-pred.rs:1:26
|
--> $DIR/not-a-pred.rs:1:26
|
||||||
|
|
|
|
||||||
LL | fn f(a: isize, b: isize) : lt(a, b) { }
|
LL | fn f(a: isize, b: isize) : lt(a, b) { }
|
||||||
| ^ expected one of `->`, `;`, `where`, or `{`
|
| ^ help: use `->` instead
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0573]: expected type, found function `lt`
|
||||||
|
--> $DIR/not-a-pred.rs:1:28
|
||||||
|
|
|
||||||
|
LL | fn f(a: isize, b: isize) : lt(a, b) { }
|
||||||
|
| ^^^^^^^^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `a`
|
||||||
|
--> $DIR/not-a-pred.rs:1:31
|
||||||
|
|
|
||||||
|
LL | fn f(a: isize, b: isize) : lt(a, b) { }
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0573]: expected type, found local variable `b`
|
||||||
|
--> $DIR/not-a-pred.rs:1:34
|
||||||
|
|
|
||||||
|
LL | fn f(a: isize, b: isize) : lt(a, b) { }
|
||||||
|
| ^ not a type
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `check` in this scope
|
||||||
|
--> $DIR/not-a-pred.rs:12:5
|
||||||
|
|
|
||||||
|
LL | check (lt(a, b));
|
||||||
|
| ^^^^^ not found in this scope
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0425, E0573.
|
||||||
|
For more information about an error, try `rustc --explain E0425`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue