about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/src/parser/path.rs20
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs16
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr8
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs18
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr35
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs17
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr24
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013.rs19
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr41
9 files changed, 197 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 953c6915068..4e4130dfc23 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -495,11 +495,16 @@ impl<'a> Parser<'a> {
             None => {
                 let after_eq = eq.shrink_to_hi();
                 let before_next = self.token.span.shrink_to_lo();
+                let the_type_placeholder = if matches!(self.token.kind, token::Comma | token::Gt) {
+                    " TheType"
+                } else {
+                    " TheType "
+                };
                 self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`")
                     .span_suggestion(
                         self.sess.source_map().next_point(eq).to(before_next),
                         "to constrain the associated type, add a type after `=`",
-                        " TheType".to_string(),
+                        the_type_placeholder.to_string(),
                         Applicability::HasPlaceholders,
                     )
                     .span_suggestion(
@@ -572,6 +577,19 @@ impl<'a> Parser<'a> {
                     return self.recover_const_arg(start, err).map(Some);
                 }
             }
+        } else if self.eat_keyword_noexpect(kw::Const) {
+            // Detect and recover from the old, pre-RFC2000 syntax for const generics.
+            let mut err = self.struct_span_err(
+                start,
+                "expected lifetime, type, or constant, found keyword `const`",
+            );
+            if self.check_const_arg() {
+                err.emit();
+                GenericArg::Const(self.parse_const_arg()?)
+            } else {
+                let after_kw_const = self.token.span;
+                return self.recover_const_arg(after_kw_const, err).map(Some);
+            }
         } else {
             return Ok(None);
         };
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs
new file mode 100644
index 00000000000..99d8e9dea91
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs
@@ -0,0 +1,16 @@
+trait Foo<const N: usize> {
+    fn do_x(&self) -> [u8; N];
+}
+
+struct Bar;
+
+const T: usize = 42;
+
+impl Foo<const 3> for Bar {
+//~^ERROR expected lifetime, type, or constant, found keyword `const`
+    fn do_x(&self) -> [u8; 3] {
+        [0u8; 3]
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr
new file mode 100644
index 00000000000..533d381fa31
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr
@@ -0,0 +1,8 @@
+error: expected lifetime, type, or constant, found keyword `const`
+  --> $DIR/issue-89013-no-assoc.rs:9:10
+   |
+LL | impl Foo<const 3> for Bar {
+   |          ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
new file mode 100644
index 00000000000..b73b3e29104
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
@@ -0,0 +1,18 @@
+trait Foo<const N: usize> {
+    fn do_x(&self) -> [u8; N];
+}
+
+struct Bar;
+
+const T: usize = 42;
+
+impl Foo<N = 3> for Bar {
+//~^ERROR cannot constrain an associated constant to a value
+//~^^ERROR this trait takes 1 generic argument but 0 generic arguments
+//~^^^ERROR associated type bindings are not allowed here
+    fn do_x(&self) -> [u8; 3] {
+        [0u8; 3]
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
new file mode 100644
index 00000000000..76828155576
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
@@ -0,0 +1,35 @@
+error: cannot constrain an associated constant to a value
+  --> $DIR/issue-89013-no-kw.rs:9:10
+   |
+LL | impl Foo<N = 3> for Bar {
+   |          -^^^-
+   |          |   |
+   |          |   ...cannot be constrained to this value
+   |          this associated constant...
+
+error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+  --> $DIR/issue-89013-no-kw.rs:9:6
+   |
+LL | impl Foo<N = 3> for Bar {
+   |      ^^^ expected 1 generic argument
+   |
+note: trait defined here, with 1 generic parameter: `N`
+  --> $DIR/issue-89013-no-kw.rs:1:7
+   |
+LL | trait Foo<const N: usize> {
+   |       ^^^       -
+help: add missing generic argument
+   |
+LL | impl Foo<N, N = 3> for Bar {
+   |          ++
+
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-89013-no-kw.rs:9:10
+   |
+LL | impl Foo<N = 3> for Bar {
+   |          ^^^^^ associated type not allowed here
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0229.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs
new file mode 100644
index 00000000000..c34936d1976
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs
@@ -0,0 +1,17 @@
+trait Foo<const N: usize> {
+    fn do_x(&self) -> [u8; N];
+}
+
+struct Bar;
+
+const T: usize = 42;
+
+impl Foo<N = type 3> for Bar {
+//~^ERROR missing type to the right of `=`
+//~^^ERROR found keyword `type`
+    fn do_x(&self) -> [u8; 3] {
+        [0u8; 3]
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr
new file mode 100644
index 00000000000..0f33f4b0df6
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr
@@ -0,0 +1,24 @@
+error: missing type to the right of `=`
+  --> $DIR/issue-89013-type.rs:9:13
+   |
+LL | impl Foo<N = type 3> for Bar {
+   |             ^
+   |
+help: to constrain the associated type, add a type after `=`
+   |
+LL | impl Foo<N = TheType type 3> for Bar {
+   |              +++++++
+help: remove the `=` if `N` is a type
+   |
+LL - impl Foo<N = type 3> for Bar {
+LL + impl Foo<N type 3> for Bar {
+   | 
+
+error: expected one of `,`, `>`, a const expression, lifetime, or type, found keyword `type`
+  --> $DIR/issue-89013-type.rs:9:14
+   |
+LL | impl Foo<N = type 3> for Bar {
+   |              ^^^^ expected one of `,`, `>`, a const expression, lifetime, or type
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs
new file mode 100644
index 00000000000..d5ded44188a
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs
@@ -0,0 +1,19 @@
+trait Foo<const N: usize> {
+    fn do_x(&self) -> [u8; N];
+}
+
+struct Bar;
+
+const T: usize = 42;
+
+impl Foo<N = const 3> for Bar {
+//~^ERROR expected lifetime, type, or constant, found keyword `const`
+//~^^ERROR cannot constrain an associated constant to a value
+//~^^^ERROR this trait takes 1 generic argument but 0 generic arguments
+//~^^^^ERROR associated type bindings are not allowed here
+    fn do_x(&self) -> [u8; 3] {
+        [0u8; 3]
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr
new file mode 100644
index 00000000000..3df459ce162
--- /dev/null
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr
@@ -0,0 +1,41 @@
+error: expected lifetime, type, or constant, found keyword `const`
+  --> $DIR/issue-89013.rs:9:14
+   |
+LL | impl Foo<N = const 3> for Bar {
+   |              ^^^^^
+
+error: cannot constrain an associated constant to a value
+  --> $DIR/issue-89013.rs:9:10
+   |
+LL | impl Foo<N = const 3> for Bar {
+   |          -^^^^^^^^^-
+   |          |         |
+   |          |         ...cannot be constrained to this value
+   |          this associated constant...
+
+error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+  --> $DIR/issue-89013.rs:9:6
+   |
+LL | impl Foo<N = const 3> for Bar {
+   |      ^^^ expected 1 generic argument
+   |
+note: trait defined here, with 1 generic parameter: `N`
+  --> $DIR/issue-89013.rs:1:7
+   |
+LL | trait Foo<const N: usize> {
+   |       ^^^       -
+help: add missing generic argument
+   |
+LL | impl Foo<N, N = const 3> for Bar {
+   |          ++
+
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-89013.rs:9:10
+   |
+LL | impl Foo<N = const 3> for Bar {
+   |          ^^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0107, E0229.
+For more information about an error, try `rustc --explain E0107`.