about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/src/parser/item.rs1
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs19
-rw-r--r--src/test/ui/type/issue-102598.rs8
-rw-r--r--src/test/ui/type/issue-102598.stderr43
4 files changed, 70 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9b8a6c47966..e1ced2eb965 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2464,7 +2464,6 @@ impl<'a> Parser<'a> {
             };
             let (pat, ty) = if is_name_required || this.is_named_param() {
                 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
-
                 let (pat, colon) = this.parse_fn_param_pat_colon()?;
                 if !colon {
                     let mut err = this.unexpected::<()>().unwrap_err();
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index b7206b57642..fc26278909c 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -613,6 +613,25 @@ impl<'a> Parser<'a> {
     /// Parses an `impl B0 + ... + Bn` type.
     fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
         // Always parse bounds greedily for better error recovery.
+        if self.token.is_lifetime() {
+            self.look_ahead(1, |t| {
+                if let token::Ident(symname, _) = t.kind {
+                    // parse pattern with "'a Sized" we're supposed to give suggestion like
+                    // "'a + Sized"
+                    self.struct_span_err(
+                        self.token.span,
+                        &format!("expected `+` between lifetime and {}", symname),
+                    )
+                    .span_suggestion_verbose(
+                        self.token.span.shrink_to_hi(),
+                        "add `+`",
+                        " +",
+                        Applicability::MaybeIncorrect,
+                    )
+                    .emit();
+                }
+            })
+        }
         let bounds = self.parse_generic_bounds(None)?;
         *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
diff --git a/src/test/ui/type/issue-102598.rs b/src/test/ui/type/issue-102598.rs
new file mode 100644
index 00000000000..93808f18b99
--- /dev/null
+++ b/src/test/ui/type/issue-102598.rs
@@ -0,0 +1,8 @@
+fn foo<'a>(_: impl 'a Sized) {}
+//~^ ERROR: expected `+` between lifetime and Sized
+//~| ERROR: expected one of `:`, `@`, or `|`, found `)`
+//~| ERROR: expected one of `)`, `+`, or `,`, found `Sized`
+//~| ERROR: at least one trait must be specified
+
+fn main(){
+}
diff --git a/src/test/ui/type/issue-102598.stderr b/src/test/ui/type/issue-102598.stderr
new file mode 100644
index 00000000000..a232395cedb
--- /dev/null
+++ b/src/test/ui/type/issue-102598.stderr
@@ -0,0 +1,43 @@
+error: expected `+` between lifetime and Sized
+  --> $DIR/issue-102598.rs:1:20
+   |
+LL | fn foo<'a>(_: impl 'a Sized) {}
+   |                    ^^
+   |
+help: add `+`
+   |
+LL | fn foo<'a>(_: impl 'a + Sized) {}
+   |                       +
+
+error: expected one of `:`, `@`, or `|`, found `)`
+  --> $DIR/issue-102598.rs:1:28
+   |
+LL | fn foo<'a>(_: impl 'a Sized) {}
+   |                            ^ expected one of `:`, `@`, or `|`
+   |
+   = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a parameter name, give it a type
+   |
+LL | fn foo<'a>(_: impl 'a Sized: TypeName) {}
+   |                            ++++++++++
+help: if this is a type, explicitly ignore the parameter name
+   |
+LL | fn foo<'a>(_: impl 'a _: Sized) {}
+   |                       ++
+
+error: expected one of `)`, `+`, or `,`, found `Sized`
+  --> $DIR/issue-102598.rs:1:23
+   |
+LL | fn foo<'a>(_: impl 'a Sized) {}
+   |                      -^^^^^ expected one of `)`, `+`, or `,`
+   |                      |
+   |                      help: missing `,`
+
+error: at least one trait must be specified
+  --> $DIR/issue-102598.rs:1:15
+   |
+LL | fn foo<'a>(_: impl 'a Sized) {}
+   |               ^^^^^^^
+
+error: aborting due to 4 previous errors
+