]> git.lizzy.rs Git - rust.git/commitdiff
Gracefully handle confusing -> with : in function return type
authormibac138 <5672750+mibac138@users.noreply.github.com>
Thu, 15 Oct 2020 19:21:45 +0000 (21:21 +0200)
committermibac138 <5672750+mibac138@users.noreply.github.com>
Thu, 3 Dec 2020 17:19:42 +0000 (18:19 +0100)
19 files changed:
compiler/rustc_parse/src/parser/expr.rs
compiler/rustc_parse/src/parser/generics.rs
compiler/rustc_parse/src/parser/item.rs
compiler/rustc_parse/src/parser/path.rs
compiler/rustc_parse/src/parser/ty.rs
src/test/ui/fn/fn-fat-arrow-return.fixed [deleted file]
src/test/ui/fn/fn-fat-arrow-return.rs [deleted file]
src/test/ui/fn/fn-fat-arrow-return.stderr [deleted file]
src/test/ui/fn/fn-fat-arrow-return2.rs [deleted file]
src/test/ui/fn/fn-fat-arrow-return2.stderr [deleted file]
src/test/ui/fn/fn-recover-return-sign.fixed [new file with mode: 0644]
src/test/ui/fn/fn-recover-return-sign.rs [new file with mode: 0644]
src/test/ui/fn/fn-recover-return-sign.stderr [new file with mode: 0644]
src/test/ui/fn/fn-recover-return-sign2.rs [new file with mode: 0644]
src/test/ui/fn/fn-recover-return-sign2.stderr [new file with mode: 0644]
src/test/ui/parser/fn-colon-return-type.rs
src/test/ui/parser/fn-colon-return-type.stderr
src/test/ui/parser/not-a-pred.rs
src/test/ui/parser/not-a-pred.stderr

index 790a0c867af8bd993972f0dc86ed48a394afe6d0..4d2167442bed6ec28afde04197ed329eb377df50 100644 (file)
@@ -1,5 +1,5 @@
 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::{SemiColonMode, SeqSep, TokenExpectType};
 use crate::maybe_recover_from_interpolated_ty_qpath;
@@ -1647,7 +1647,8 @@ fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
             self.expect_or()?;
             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 }))
     }
index dd99a7587dd549660034495391ca46bd72a73790..ed8d4f78426ac7a242c46952fe03f4ec0ea39a96 100644 (file)
@@ -240,7 +240,7 @@ fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> {
 
         // Parse type with mandatory colon and (possibly empty) bounds,
         // 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) {
             let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
             Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
index 9e342a0d681319f24b9dda39550d651fb4923395..ff0323a107a747421cfdcca3be83d0789cbbd45e 100644 (file)
@@ -1,5 +1,5 @@
 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 crate::maybe_whole;
@@ -1514,7 +1514,7 @@ fn parse_fn(
         let header = self.parse_fn_front_matter()?; // `const ... fn`
         let ident = self.parse_ident()?; // `foo`
         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`
 
         let mut sig_hi = self.prev_token.span;
@@ -1645,10 +1645,11 @@ pub(super) fn parse_fn_decl(
         &mut self,
         req_name: ReqName,
         ret_allow_plus: AllowPlus,
+        recover_return_sign: RecoverReturnSign,
     ) -> PResult<'a, P<FnDecl>> {
         Ok(P(FnDecl {
             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)?,
         }))
     }
 
index 311a4829fcfc54c0a16e045b31d2e703ca03d043..4510e86e0341fd899e8240eddb8884906acba5b3 100644 (file)
@@ -1,4 +1,4 @@
-use super::ty::{AllowPlus, RecoverFatArrow, RecoverQPath};
+use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{Parser, TokenType};
 use crate::maybe_whole;
 use rustc_ast::ptr::P;
@@ -232,7 +232,7 @@ pub(super) fn parse_path_segment(&mut self, style: PathStyle) -> PResult<'a, Pat
                     let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
                     let span = ident.span.to(self.prev_token.span);
                     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()
                 };
 
index ff19c5cfa856414a4c661ada930fef2d94d1d18c..ee0dc8f6304a7b828cb0c685329250c06dc93593 100644 (file)
@@ -43,12 +43,23 @@ pub(super) enum RecoverQPath {
     No,
 }
 
-#[derive(PartialEq)]
-pub(super) enum RecoverFatArrow {
+#[derive(Copy, Clone, PartialEq)]
+pub(super) enum RecoverReturnSign {
     Yes,
+    OnlyFatArrow,
     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?
 #[derive(PartialEq)]
 enum AllowCVariadic {
@@ -68,14 +79,24 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
 impl<'a> Parser<'a> {
     /// Parses a type.
     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.
     /// The difference from `parse_ty` is that this version allows `...`
     /// (`CVarArgs`) at the top level of the type.
     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.
@@ -85,7 +106,22 @@ pub(super) fn parse_ty_for_param(&mut self) -> PResult<'a, P<Ty>> {
     /// Example 2: `value1 as TYPE + value2`
     ///     `+` is prohibited to avoid interactions with expression grammar.
     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.
@@ -93,13 +129,18 @@ pub(super) fn parse_ret_ty(
         &mut self,
         allow_plus: AllowPlus,
         recover_qpath: RecoverQPath,
-        recover_fat_arrow: RecoverFatArrow,
+        recover_return_sign: RecoverReturnSign,
     ) -> PResult<'a, FnRetTy> {
         Ok(if self.eat(&token::RArrow) {
             // 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)
-        } 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
             // actually expected and could only confuse users
             self.bump();
@@ -111,7 +152,12 @@ pub(super) fn parse_ret_ty(
                     Applicability::MachineApplicable,
                 )
                 .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)
         } else {
             FnRetTy::Default(self.token.span.shrink_to_lo())
@@ -123,6 +169,7 @@ fn parse_ty_common(
         allow_plus: AllowPlus,
         recover_qpath: RecoverQPath,
         allow_c_variadic: AllowCVariadic,
+        recover_return_sign: RecoverReturnSign,
     ) -> PResult<'a, P<Ty>> {
         let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
         maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
@@ -150,14 +197,14 @@ fn parse_ty_common(
             TyKind::Infer
         } else if self.check_fn_front_matter() {
             // 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) {
             // 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> Trait1<'lt> + Trait2 + 'a`
             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
             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 {
                 let path = self.parse_path(PathStyle::Type)?;
                 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
@@ -359,9 +406,14 @@ fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> {
     /// Function Style    ABI  Parameter types
     /// ```
     /// 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 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);
         if let ast::Const::Yes(span) = constness {
             self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
diff --git a/src/test/ui/fn/fn-fat-arrow-return.fixed b/src/test/ui/fn/fn-fat-arrow-return.fixed
deleted file mode 100644 (file)
index 0acca85..0000000
+++ /dev/null
@@ -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() {
-}
diff --git a/src/test/ui/fn/fn-fat-arrow-return.rs b/src/test/ui/fn/fn-fat-arrow-return.rs
deleted file mode 100644 (file)
index 4bdcd70..0000000
+++ /dev/null
@@ -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() {
-}
diff --git a/src/test/ui/fn/fn-fat-arrow-return.stderr b/src/test/ui/fn/fn-fat-arrow-return.stderr
deleted file mode 100644 (file)
index 1fcdb18..0000000
+++ /dev/null
@@ -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
-
diff --git a/src/test/ui/fn/fn-fat-arrow-return2.rs b/src/test/ui/fn/fn-fat-arrow-return2.rs
deleted file mode 100644 (file)
index 316fa2c..0000000
+++ /dev/null
@@ -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));
-}
diff --git a/src/test/ui/fn/fn-fat-arrow-return2.stderr b/src/test/ui/fn/fn-fat-arrow-return2.stderr
deleted file mode 100644 (file)
index a6f9fe3..0000000
+++ /dev/null
@@ -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
-
diff --git a/src/test/ui/fn/fn-recover-return-sign.fixed b/src/test/ui/fn/fn-recover-return-sign.fixed
new file mode 100644 (file)
index 0000000..076be6a
--- /dev/null
@@ -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));
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign.rs b/src/test/ui/fn/fn-recover-return-sign.rs
new file mode 100644 (file)
index 0000000..0656023
--- /dev/null
@@ -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));
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign.stderr b/src/test/ui/fn/fn-recover-return-sign.stderr
new file mode 100644 (file)
index 0000000..9831097
--- /dev/null
@@ -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
+
diff --git a/src/test/ui/fn/fn-recover-return-sign2.rs b/src/test/ui/fn/fn-recover-return-sign2.rs
new file mode 100644 (file)
index 0000000..b6a6a1e
--- /dev/null
@@ -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!()
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign2.stderr b/src/test/ui/fn/fn-recover-return-sign2.stderr
new file mode 100644 (file)
index 0000000..d62cacd
--- /dev/null
@@ -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
+
index c791fb3ae674970948a888bdc260d629a8bad221..0001ef57c99024d997173271754a4468739aec17 100644 (file)
@@ -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
 }
 
index 92df9bc60bd3c1162d8f3d51c8a5e8af1fdcce5a..1de9187820560779ae5b79ea4f861576ba1b78b2 100644 (file)
@@ -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
    |
 LL | fn foo(x: i32): i32 {
-   |               ^ expected one of `->`, `;`, `where`, or `{`
+   |               ^ help: use `->` instead
 
 error: aborting due to previous error
 
index 1b3d9bf66bb6072643767443a68dd6b82a1df0f8..5518b554d8e530e813126db6be82bc91777b692a 100644 (file)
@@ -1,6 +1,15 @@
 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 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);
+}
index ec413c5594c44429e497920a88298429f64a5ef3..bcc64a687fd0cc108734a6a1bf0a4d0b6a960d9c 100644 (file)
@@ -1,8 +1,34 @@
-error: expected one of `->`, `;`, `where`, or `{`, found `:`
+error: return types are denoted using `->`
   --> $DIR/not-a-pred.rs:1:26
    |
 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`.