summaryrefslogtreecommitdiffstats
path: root/src/test/ui/parser
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/parser
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/test/ui/parser/ascii-only-character-escape.rs6
-rw-r--r--src/test/ui/parser/ascii-only-character-escape.stderr20
-rw-r--r--src/test/ui/parser/assoc-const-underscore-semantic-fail.rs17
-rw-r--r--src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr27
-rw-r--r--src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs18
-rw-r--r--src/test/ui/parser/assoc-oddities-1.rs11
-rw-r--r--src/test/ui/parser/assoc-oddities-1.stderr8
-rw-r--r--src/test/ui/parser/assoc-oddities-2.rs6
-rw-r--r--src/test/ui/parser/assoc-oddities-2.stderr8
-rw-r--r--src/test/ui/parser/assoc-static-semantic-fail.rs52
-rw-r--r--src/test/ui/parser/assoc-static-semantic-fail.stderr177
-rw-r--r--src/test/ui/parser/assoc-static-syntactic-fail.rs33
-rw-r--r--src/test/ui/parser/assoc-static-syntactic-fail.stderr122
-rw-r--r--src/test/ui/parser/assoc-type-in-type-arg.rs11
-rw-r--r--src/test/ui/parser/assoc-type-in-type-arg.stderr8
-rw-r--r--src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs16
-rw-r--r--src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr14
-rw-r--r--src/test/ui/parser/attr-bad-meta-2.rs2
-rw-r--r--src/test/ui/parser/attr-bad-meta-2.stderr8
-rw-r--r--src/test/ui/parser/attr-bad-meta-3.rs2
-rw-r--r--src/test/ui/parser/attr-bad-meta-3.stderr8
-rw-r--r--src/test/ui/parser/attr-bad-meta.rs2
-rw-r--r--src/test/ui/parser/attr-bad-meta.stderr8
-rw-r--r--src/test/ui/parser/attr-before-eof.rs3
-rw-r--r--src/test/ui/parser/attr-before-eof.stderr8
-rw-r--r--src/test/ui/parser/attr-dangling-in-fn.rs8
-rw-r--r--src/test/ui/parser/attr-dangling-in-fn.stderr8
-rw-r--r--src/test/ui/parser/attr-dangling-in-mod.rs6
-rw-r--r--src/test/ui/parser/attr-dangling-in-mod.stderr8
-rw-r--r--src/test/ui/parser/attr-stmt-expr-attr-bad.rs111
-rw-r--r--src/test/ui/parser/attr-stmt-expr-attr-bad.stderr445
-rw-r--r--src/test/ui/parser/attr-with-a-semicolon.rs4
-rw-r--r--src/test/ui/parser/attr-with-a-semicolon.stderr14
-rw-r--r--src/test/ui/parser/attr.rs6
-rw-r--r--src/test/ui/parser/attr.stderr17
-rw-r--r--src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs3
-rw-r--r--src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr8
-rw-r--r--src/test/ui/parser/attrs-after-extern-mod.rs7
-rw-r--r--src/test/ui/parser/attrs-after-extern-mod.stderr12
-rw-r--r--src/test/ui/parser/bad-char-literals.rs20
-rw-r--r--src/test/ui/parser/bad-char-literals.stderr28
-rw-r--r--src/test/ui/parser/bad-crate-name.rs5
-rw-r--r--src/test/ui/parser/bad-crate-name.stderr20
-rw-r--r--src/test/ui/parser/bad-escape-suggest-raw-string.rs7
-rw-r--r--src/test/ui/parser/bad-escape-suggest-raw-string.stderr14
-rw-r--r--src/test/ui/parser/bad-fn-ptr-qualifier.fixed26
-rw-r--r--src/test/ui/parser/bad-fn-ptr-qualifier.rs26
-rw-r--r--src/test/ui/parser/bad-fn-ptr-qualifier.stderr146
-rw-r--r--src/test/ui/parser/bad-if-statements.rs38
-rw-r--r--src/test/ui/parser/bad-if-statements.stderr86
-rw-r--r--src/test/ui/parser/bad-interpolated-block.rs15
-rw-r--r--src/test/ui/parser/bad-interpolated-block.stderr39
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.rs26
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.stderr114
-rw-r--r--src/test/ui/parser/bad-match.rs4
-rw-r--r--src/test/ui/parser/bad-match.stderr8
-rw-r--r--src/test/ui/parser/bad-name.rs5
-rw-r--r--src/test/ui/parser/bad-name.stderr8
-rw-r--r--src/test/ui/parser/bad-pointer-type.rs5
-rw-r--r--src/test/ui/parser/bad-pointer-type.stderr10
-rw-r--r--src/test/ui/parser/bad-struct-following-where.rs2
-rw-r--r--src/test/ui/parser/bad-struct-following-where.stderr8
-rw-r--r--src/test/ui/parser/bad-value-ident-false.rs2
-rw-r--r--src/test/ui/parser/bad-value-ident-false.stderr13
-rw-r--r--src/test/ui/parser/bad-value-ident-true.rs2
-rw-r--r--src/test/ui/parser/bad-value-ident-true.stderr13
-rw-r--r--src/test/ui/parser/bare-struct-body.rs15
-rw-r--r--src/test/ui/parser/bare-struct-body.stderr41
-rw-r--r--src/test/ui/parser/bastion-of-the-turbofish.rs43
-rw-r--r--src/test/ui/parser/better-expected.rs3
-rw-r--r--src/test/ui/parser/better-expected.stderr10
-rw-r--r--src/test/ui/parser/bind-struct-early-modifiers.rs7
-rw-r--r--src/test/ui/parser/bind-struct-early-modifiers.stderr10
-rw-r--r--src/test/ui/parser/block-no-opening-brace.rs31
-rw-r--r--src/test/ui/parser/block-no-opening-brace.stderr55
-rw-r--r--src/test/ui/parser/bound-single-question-mark.rs1
-rw-r--r--src/test/ui/parser/bound-single-question-mark.stderr8
-rw-r--r--src/test/ui/parser/bounds-lifetime-1.rs3
-rw-r--r--src/test/ui/parser/bounds-lifetime-1.stderr8
-rw-r--r--src/test/ui/parser/bounds-lifetime-2.rs3
-rw-r--r--src/test/ui/parser/bounds-lifetime-2.stderr8
-rw-r--r--src/test/ui/parser/bounds-lifetime-where-1.rs3
-rw-r--r--src/test/ui/parser/bounds-lifetime-where-1.stderr8
-rw-r--r--src/test/ui/parser/bounds-lifetime-where.rs10
-rw-r--r--src/test/ui/parser/bounds-lifetime-where.stderr8
-rw-r--r--src/test/ui/parser/bounds-lifetime.rs11
-rw-r--r--src/test/ui/parser/bounds-lifetime.stderr8
-rw-r--r--src/test/ui/parser/bounds-obj-parens.rs7
-rw-r--r--src/test/ui/parser/bounds-type-where.rs11
-rw-r--r--src/test/ui/parser/bounds-type-where.stderr8
-rw-r--r--src/test/ui/parser/bounds-type.rs18
-rw-r--r--src/test/ui/parser/bounds-type.stderr14
-rw-r--r--src/test/ui/parser/byte-literals.rs12
-rw-r--r--src/test/ui/parser/byte-literals.stderr54
-rw-r--r--src/test/ui/parser/byte-string-literals.rs9
-rw-r--r--src/test/ui/parser/byte-string-literals.stderr50
-rw-r--r--src/test/ui/parser/can-begin-expr-check.rs20
-rw-r--r--src/test/ui/parser/can-begin-expr-check.stderr8
-rw-r--r--src/test/ui/parser/chained-comparison-suggestion.rs53
-rw-r--r--src/test/ui/parser/chained-comparison-suggestion.stderr160
-rw-r--r--src/test/ui/parser/char/whitespace-character-literal.rs10
-rw-r--r--src/test/ui/parser/char/whitespace-character-literal.stderr16
-rw-r--r--src/test/ui/parser/circular_modules_hello.rs8
-rw-r--r--src/test/ui/parser/circular_modules_main.rs12
-rw-r--r--src/test/ui/parser/circular_modules_main.stderr25
-rw-r--r--src/test/ui/parser/class-implements-bad-trait.rs9
-rw-r--r--src/test/ui/parser/class-implements-bad-trait.stderr8
-rw-r--r--src/test/ui/parser/closure-return-syntax.rs7
-rw-r--r--src/test/ui/parser/closure-return-syntax.stderr13
-rw-r--r--src/test/ui/parser/column-offset-1-based.rs1
-rw-r--r--src/test/ui/parser/column-offset-1-based.stderr8
-rw-r--r--src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs15
-rw-r--r--src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr47
-rw-r--r--src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs9
-rw-r--r--src/test/ui/parser/default-on-wrong-item-kind.rs140
-rw-r--r--src/test/ui/parser/default-on-wrong-item-kind.stderr760
-rw-r--r--src/test/ui/parser/default-unmatched-assoc.rs16
-rw-r--r--src/test/ui/parser/default-unmatched-assoc.stderr54
-rw-r--r--src/test/ui/parser/default-unmatched-extern.rs8
-rw-r--r--src/test/ui/parser/default-unmatched-extern.stderr28
-rw-r--r--src/test/ui/parser/default-unmatched.rs6
-rw-r--r--src/test/ui/parser/default-unmatched.stderr16
-rw-r--r--src/test/ui/parser/default.rs28
-rw-r--r--src/test/ui/parser/default.stderr48
-rw-r--r--src/test/ui/parser/do-catch-suggests-try.rs10
-rw-r--r--src/test/ui/parser/do-catch-suggests-try.stderr19
-rw-r--r--src/test/ui/parser/doc-after-struct-field.rs16
-rw-r--r--src/test/ui/parser/doc-after-struct-field.stderr19
-rw-r--r--src/test/ui/parser/doc-before-attr.rs4
-rw-r--r--src/test/ui/parser/doc-before-attr.stderr10
-rw-r--r--src/test/ui/parser/doc-before-eof.rs3
-rw-r--r--src/test/ui/parser/doc-before-eof.stderr8
-rw-r--r--src/test/ui/parser/doc-before-extern-rbrace.rs6
-rw-r--r--src/test/ui/parser/doc-before-extern-rbrace.stderr11
-rw-r--r--src/test/ui/parser/doc-before-fn-rbrace.rs5
-rw-r--r--src/test/ui/parser/doc-before-fn-rbrace.stderr11
-rw-r--r--src/test/ui/parser/doc-before-identifier.rs7
-rw-r--r--src/test/ui/parser/doc-before-identifier.stderr8
-rw-r--r--src/test/ui/parser/doc-before-mod-rbrace.rs6
-rw-r--r--src/test/ui/parser/doc-before-mod-rbrace.stderr8
-rw-r--r--src/test/ui/parser/doc-before-rbrace.rs5
-rw-r--r--src/test/ui/parser/doc-before-rbrace.stderr11
-rw-r--r--src/test/ui/parser/doc-before-semi.rs6
-rw-r--r--src/test/ui/parser/doc-before-semi.stderr11
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-1.rs10
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-1.stderr11
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-2.rs9
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-2.stderr11
-rw-r--r--src/test/ui/parser/doc-comment-in-if-statement.rs5
-rw-r--r--src/test/ui/parser/doc-comment-in-if-statement.stderr25
-rw-r--r--src/test/ui/parser/doc-comment-in-stmt.rs20
-rw-r--r--src/test/ui/parser/doc-comment-in-stmt.stderr50
-rw-r--r--src/test/ui/parser/doc-inside-trait-item.rs6
-rw-r--r--src/test/ui/parser/doc-inside-trait-item.stderr11
-rw-r--r--src/test/ui/parser/dotdotdot-expr.rs4
-rw-r--r--src/test/ui/parser/dotdotdot-expr.stderr17
-rw-r--r--src/test/ui/parser/duplicate-visibility.rs9
-rw-r--r--src/test/ui/parser/duplicate-visibility.stderr22
-rw-r--r--src/test/ui/parser/duplicate-where-clauses.rs19
-rw-r--r--src/test/ui/parser/duplicate-where-clauses.stderr80
-rw-r--r--src/test/ui/parser/dyn-trait-compatibility.rs14
-rw-r--r--src/test/ui/parser/dyn-trait-compatibility.stderr58
-rw-r--r--src/test/ui/parser/else-no-if.rs32
-rw-r--r--src/test/ui/parser/else-no-if.stderr50
-rw-r--r--src/test/ui/parser/emoji-identifiers.rs19
-rw-r--r--src/test/ui/parser/emoji-identifiers.stderr91
-rw-r--r--src/test/ui/parser/empty-impl-semicolon.rs1
-rw-r--r--src/test/ui/parser/empty-impl-semicolon.stderr8
-rw-r--r--src/test/ui/parser/expr-as-stmt-2.rs10
-rw-r--r--src/test/ui/parser/expr-as-stmt-2.stderr51
-rw-r--r--src/test/ui/parser/expr-as-stmt.fixed67
-rw-r--r--src/test/ui/parser/expr-as-stmt.rs67
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr216
-rw-r--r--src/test/ui/parser/extern-abi-from-mac-literal-frag.rs47
-rw-r--r--src/test/ui/parser/extern-abi-raw-strings.rs13
-rw-r--r--src/test/ui/parser/extern-abi-string-escaping.rs13
-rw-r--r--src/test/ui/parser/extern-abi-syntactic.rs17
-rw-r--r--src/test/ui/parser/extern-crate-async.rs12
-rw-r--r--src/test/ui/parser/extern-crate-unexpected-token.rs1
-rw-r--r--src/test/ui/parser/extern-crate-unexpected-token.stderr8
-rw-r--r--src/test/ui/parser/extern-expected-fn-or-brace.rs3
-rw-r--r--src/test/ui/parser/extern-expected-fn-or-brace.stderr8
-rw-r--r--src/test/ui/parser/extern-foreign-crate.rs4
-rw-r--r--src/test/ui/parser/extern-foreign-crate.stderr8
-rw-r--r--src/test/ui/parser/extern-no-fn.rs6
-rw-r--r--src/test/ui/parser/extern-no-fn.stderr12
-rw-r--r--src/test/ui/parser/float-field-interpolated.rs17
-rw-r--r--src/test/ui/parser/float-field-interpolated.stderr46
-rw-r--r--src/test/ui/parser/float-field.rs62
-rw-r--r--src/test/ui/parser/float-field.stderr349
-rw-r--r--src/test/ui/parser/float-literals.rs9
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.rs30
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.stderr61
-rw-r--r--src/test/ui/parser/fn-body-eq-expr-semi.rs23
-rw-r--r--src/test/ui/parser/fn-body-eq-expr-semi.stderr117
-rw-r--r--src/test/ui/parser/fn-body-optional-semantic-fail.rs27
-rw-r--r--src/test/ui/parser/fn-body-optional-semantic-fail.stderr40
-rw-r--r--src/test/ui/parser/fn-body-optional-syntactic-pass.rs31
-rw-r--r--src/test/ui/parser/fn-colon-return-type.rs6
-rw-r--r--src/test/ui/parser/fn-colon-return-type.stderr8
-rw-r--r--src/test/ui/parser/fn-field-parse-error-ice.rs10
-rw-r--r--src/test/ui/parser/fn-field-parse-error-ice.stderr24
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.rs60
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr330
-rw-r--r--src/test/ui/parser/fn-header-syntactic-pass.rs47
-rw-r--r--src/test/ui/parser/fn-returns-fn-pointer.rs6
-rw-r--r--src/test/ui/parser/foreign-const-semantic-fail.rs9
-rw-r--r--src/test/ui/parser/foreign-const-semantic-fail.stderr35
-rw-r--r--src/test/ui/parser/foreign-const-syntactic-fail.rs9
-rw-r--r--src/test/ui/parser/foreign-const-syntactic-fail.stderr22
-rw-r--r--src/test/ui/parser/foreign-static-semantic-fail.rs8
-rw-r--r--src/test/ui/parser/foreign-static-semantic-fail.stderr27
-rw-r--r--src/test/ui/parser/foreign-static-syntactic-pass.rs11
-rw-r--r--src/test/ui/parser/foreign-ty-semantic-fail.rs18
-rw-r--r--src/test/ui/parser/foreign-ty-semantic-fail.stderr65
-rw-r--r--src/test/ui/parser/foreign-ty-syntactic-pass.rs12
-rw-r--r--src/test/ui/parser/if-block-unreachable-expr.rs8
-rw-r--r--src/test/ui/parser/if-in-in.fixed7
-rw-r--r--src/test/ui/parser/if-in-in.rs7
-rw-r--r--src/test/ui/parser/if-in-in.stderr10
-rw-r--r--src/test/ui/parser/impl-item-const-pass.rs8
-rw-r--r--src/test/ui/parser/impl-item-const-semantic-fail.rs7
-rw-r--r--src/test/ui/parser/impl-item-const-semantic-fail.stderr10
-rw-r--r--src/test/ui/parser/impl-item-fn-no-body-pass.rs8
-rw-r--r--src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs7
-rw-r--r--src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr10
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-pass.rs11
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs22
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr83
-rw-r--r--src/test/ui/parser/impl-parsing.rs10
-rw-r--r--src/test/ui/parser/impl-parsing.stderr40
-rw-r--r--src/test/ui/parser/impl-qpath.rs7
-rw-r--r--src/test/ui/parser/import-from-path.rs2
-rw-r--r--src/test/ui/parser/import-from-path.stderr10
-rw-r--r--src/test/ui/parser/import-from-rename.rs10
-rw-r--r--src/test/ui/parser/import-from-rename.stderr10
-rw-r--r--src/test/ui/parser/import-glob-path.rs2
-rw-r--r--src/test/ui/parser/import-glob-path.stderr10
-rw-r--r--src/test/ui/parser/import-glob-rename.rs10
-rw-r--r--src/test/ui/parser/import-glob-rename.stderr10
-rw-r--r--src/test/ui/parser/increment-autofix.fixed31
-rw-r--r--src/test/ui/parser/increment-autofix.rs31
-rw-r--r--src/test/ui/parser/increment-autofix.stderr52
-rw-r--r--src/test/ui/parser/increment-notfixed.rs61
-rw-r--r--src/test/ui/parser/increment-notfixed.stderr102
-rw-r--r--src/test/ui/parser/inner-attr-after-doc-comment.rs8
-rw-r--r--src/test/ui/parser/inner-attr-after-doc-comment.stderr23
-rw-r--r--src/test/ui/parser/inner-attr-in-trait-def.rs9
-rw-r--r--src/test/ui/parser/inner-attr.rs4
-rw-r--r--src/test/ui/parser/inner-attr.stderr20
-rw-r--r--src/test/ui/parser/int-literal-too-large-span.rs7
-rw-r--r--src/test/ui/parser/int-literal-too-large-span.stderr8
-rw-r--r--src/test/ui/parser/intersection-patterns.rs40
-rw-r--r--src/test/ui/parser/intersection-patterns.stderr33
-rw-r--r--src/test/ui/parser/inverted-parameters.rs32
-rw-r--r--src/test/ui/parser/inverted-parameters.stderr61
-rw-r--r--src/test/ui/parser/issue-61858.rs3
-rw-r--r--src/test/ui/parser/issue-61858.stderr14
-rw-r--r--src/test/ui/parser/issue-68091-unicode-ident-after-if.rs10
-rw-r--r--src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr10
-rw-r--r--src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs9
-rw-r--r--src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr8
-rw-r--r--src/test/ui/parser/issue-81804.rs9
-rw-r--r--src/test/ui/parser/issue-81804.stderr41
-rw-r--r--src/test/ui/parser/issue-81827.rs11
-rw-r--r--src/test/ui/parser/issue-81827.stderr35
-rw-r--r--src/test/ui/parser/issue-87694-duplicated-pub.rs5
-rw-r--r--src/test/ui/parser/issue-87694-duplicated-pub.stderr17
-rw-r--r--src/test/ui/parser/issue-87694-misplaced-pub.rs5
-rw-r--r--src/test/ui/parser/issue-87694-misplaced-pub.stderr11
-rw-r--r--src/test/ui/parser/issue-90728.rs6
-rw-r--r--src/test/ui/parser/issue-90728.stderr20
-rw-r--r--src/test/ui/parser/issue-91421.rs9
-rw-r--r--src/test/ui/parser/issue-91421.stderr14
-rw-r--r--src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed13
-rw-r--r--src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs13
-rw-r--r--src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr8
-rw-r--r--src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs3
-rw-r--r--src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs13
-rw-r--r--src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs3
-rw-r--r--src/test/ui/parser/issues/issue-10392-2.fixed9
-rw-r--r--src/test/ui/parser/issues/issue-10392-2.rs9
-rw-r--r--src/test/ui/parser/issues/issue-10392-2.stderr12
-rw-r--r--src/test/ui/parser/issues/issue-10392.rs7
-rw-r--r--src/test/ui/parser/issues/issue-10392.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-10636-1.rs8
-rw-r--r--src/test/ui/parser/issues/issue-10636-1.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-10636-2.rs11
-rw-r--r--src/test/ui/parser/issues/issue-10636-2.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-13483.rs17
-rw-r--r--src/test/ui/parser/issues/issue-13483.stderr18
-rw-r--r--src/test/ui/parser/issues/issue-14303-enum.rs6
-rw-r--r--src/test/ui/parser/issues/issue-14303-enum.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-fn-def.rs4
-rw-r--r--src/test/ui/parser/issues/issue-14303-fn-def.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-fncall.full.stderr9
-rw-r--r--src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr9
-rw-r--r--src/test/ui/parser/issues/issue-14303-fncall.rs20
-rw-r--r--src/test/ui/parser/issues/issue-14303-impl.rs6
-rw-r--r--src/test/ui/parser/issues/issue-14303-impl.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-path.rs13
-rw-r--r--src/test/ui/parser/issues/issue-14303-path.stderr9
-rw-r--r--src/test/ui/parser/issues/issue-14303-struct.rs6
-rw-r--r--src/test/ui/parser/issues/issue-14303-struct.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-14303-trait.rs4
-rw-r--r--src/test/ui/parser/issues/issue-14303-trait.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-15914.rs4
-rw-r--r--src/test/ui/parser/issues/issue-15914.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-15980.rs17
-rw-r--r--src/test/ui/parser/issues/issue-15980.stderr25
-rw-r--r--src/test/ui/parser/issues/issue-1655.rs10
-rw-r--r--src/test/ui/parser/issues/issue-1655.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-17383.rs7
-rw-r--r--src/test/ui/parser/issues/issue-17383.stderr15
-rw-r--r--src/test/ui/parser/issues/issue-17718-const-mut.rs7
-rw-r--r--src/test/ui/parser/issues/issue-17718-const-mut.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-17904-2.rs3
-rw-r--r--src/test/ui/parser/issues/issue-17904-2.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-17904.rs6
-rw-r--r--src/test/ui/parser/issues/issue-17904.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-1802-1.rs7
-rw-r--r--src/test/ui/parser/issues/issue-1802-1.stderr9
-rw-r--r--src/test/ui/parser/issues/issue-1802-2.rs7
-rw-r--r--src/test/ui/parser/issues/issue-1802-2.stderr9
-rw-r--r--src/test/ui/parser/issues/issue-19096.rs10
-rw-r--r--src/test/ui/parser/issues/issue-19096.stderr14
-rw-r--r--src/test/ui/parser/issues/issue-19398.rs6
-rw-r--r--src/test/ui/parser/issues/issue-19398.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-1.rs36
-rw-r--r--src/test/ui/parser/issues/issue-20616-1.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-20616-2.rs36
-rw-r--r--src/test/ui/parser/issues/issue-20616-2.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-3.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-3.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-4.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-4.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-5.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-5.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-6.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-6.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-7.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-7.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-20616-8.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-8.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-20616-9.rs35
-rw-r--r--src/test/ui/parser/issues/issue-20616-9.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-20711-2.rs10
-rw-r--r--src/test/ui/parser/issues/issue-20711-2.stderr14
-rw-r--r--src/test/ui/parser/issues/issue-20711.rs8
-rw-r--r--src/test/ui/parser/issues/issue-20711.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-21146.rs3
-rw-r--r--src/test/ui/parser/issues/issue-21146.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-21153.rs6
-rw-r--r--src/test/ui/parser/issues/issue-21153.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-21475.rs19
-rw-r--r--src/test/ui/parser/issues/issue-22647.rs15
-rw-r--r--src/test/ui/parser/issues/issue-22647.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-22712.rs9
-rw-r--r--src/test/ui/parser/issues/issue-22712.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-2354-1.rs1
-rw-r--r--src/test/ui/parser/issues/issue-2354-1.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-2354.rs15
-rw-r--r--src/test/ui/parser/issues/issue-2354.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-23620-invalid-escapes.rs34
-rw-r--r--src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr94
-rw-r--r--src/test/ui/parser/issues/issue-24197.rs3
-rw-r--r--src/test/ui/parser/issues/issue-24197.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-24375.rs9
-rw-r--r--src/test/ui/parser/issues/issue-24375.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-24780.rs9
-rw-r--r--src/test/ui/parser/issues/issue-24780.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-27255.rs10
-rw-r--r--src/test/ui/parser/issues/issue-27255.stderr22
-rw-r--r--src/test/ui/parser/issues/issue-30318.fixed27
-rw-r--r--src/test/ui/parser/issues/issue-30318.rs27
-rw-r--r--src/test/ui/parser/issues/issue-30318.stderr81
-rw-r--r--src/test/ui/parser/issues/issue-3036.fixed7
-rw-r--r--src/test/ui/parser/issues/issue-3036.rs7
-rw-r--r--src/test/ui/parser/issues/issue-3036.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-31804.rs6
-rw-r--r--src/test/ui/parser/issues/issue-31804.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-32214.rs6
-rw-r--r--src/test/ui/parser/issues/issue-32214.stderr15
-rw-r--r--src/test/ui/parser/issues/issue-32446.rs4
-rw-r--r--src/test/ui/parser/issues/issue-32446.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-32501.rs9
-rw-r--r--src/test/ui/parser/issues/issue-32501.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-32505.rs5
-rw-r--r--src/test/ui/parser/issues/issue-32505.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-33262.rs6
-rw-r--r--src/test/ui/parser/issues/issue-33262.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-33413.rs9
-rw-r--r--src/test/ui/parser/issues/issue-33413.stderr22
-rw-r--r--src/test/ui/parser/issues/issue-33418.fixed19
-rw-r--r--src/test/ui/parser/issues/issue-33418.rs21
-rw-r--r--src/test/ui/parser/issues/issue-33418.stderr36
-rw-r--r--src/test/ui/parser/issues/issue-33455.rs1
-rw-r--r--src/test/ui/parser/issues/issue-33455.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-34222-1.rs3
-rw-r--r--src/test/ui/parser/issues/issue-34222-1.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-34255-1.rs10
-rw-r--r--src/test/ui/parser/issues/issue-34255-1.stderr18
-rw-r--r--src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs171
-rw-r--r--src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr472
-rw-r--r--src/test/ui/parser/issues/issue-41155.rs7
-rw-r--r--src/test/ui/parser/issues/issue-41155.stderr22
-rw-r--r--src/test/ui/parser/issues/issue-43196.rs6
-rw-r--r--src/test/ui/parser/issues/issue-43196.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-43692.rs3
-rw-r--r--src/test/ui/parser/issues/issue-43692.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-44021.rs6
-rw-r--r--src/test/ui/parser/issues/issue-44021.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-44406.rs10
-rw-r--r--src/test/ui/parser/issues/issue-44406.stderr33
-rw-r--r--src/test/ui/parser/issues/issue-45296.rs6
-rw-r--r--src/test/ui/parser/issues/issue-45296.stderr17
-rw-r--r--src/test/ui/parser/issues/issue-46186.fixed8
-rw-r--r--src/test/ui/parser/issues/issue-46186.rs8
-rw-r--r--src/test/ui/parser/issues/issue-46186.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs44
-rw-r--r--src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr62
-rw-r--r--src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs34
-rw-r--r--src/test/ui/parser/issues/issue-48508-aux.rs7
-rw-r--r--src/test/ui/parser/issues/issue-48508.rs20
-rw-r--r--src/test/ui/parser/issues/issue-48636.fixed12
-rw-r--r--src/test/ui/parser/issues/issue-48636.rs12
-rw-r--r--src/test/ui/parser/issues/issue-48636.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-49040.rs3
-rw-r--r--src/test/ui/parser/issues/issue-49040.stderr15
-rw-r--r--src/test/ui/parser/issues/issue-51602.rs6
-rw-r--r--src/test/ui/parser/issues/issue-51602.stderr14
-rw-r--r--src/test/ui/parser/issues/issue-52496.rs12
-rw-r--r--src/test/ui/parser/issues/issue-52496.stderr38
-rw-r--r--src/test/ui/parser/issues/issue-54521-1.rs16
-rw-r--r--src/test/ui/parser/issues/issue-54521-2.fixed22
-rw-r--r--src/test/ui/parser/issues/issue-54521-2.rs22
-rw-r--r--src/test/ui/parser/issues/issue-54521-2.stderr26
-rw-r--r--src/test/ui/parser/issues/issue-54521-3.fixed22
-rw-r--r--src/test/ui/parser/issues/issue-54521-3.rs22
-rw-r--r--src/test/ui/parser/issues/issue-54521-3.stderr26
-rw-r--r--src/test/ui/parser/issues/issue-5544-a.rs4
-rw-r--r--src/test/ui/parser/issues/issue-5544-a.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-5544-b.rs4
-rw-r--r--src/test/ui/parser/issues/issue-5544-b.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-56031.rs6
-rw-r--r--src/test/ui/parser/issues/issue-56031.stderr18
-rw-r--r--src/test/ui/parser/issues/issue-57198.rs8
-rw-r--r--src/test/ui/parser/issues/issue-57198.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-57684.fixed37
-rw-r--r--src/test/ui/parser/issues/issue-57684.rs37
-rw-r--r--src/test/ui/parser/issues/issue-57684.stderr18
-rw-r--r--src/test/ui/parser/issues/issue-57819.fixed47
-rw-r--r--src/test/ui/parser/issues/issue-57819.rs47
-rw-r--r--src/test/ui/parser/issues/issue-57819.stderr44
-rw-r--r--src/test/ui/parser/issues/issue-5806.rs7
-rw-r--r--src/test/ui/parser/issues/issue-5806.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs4
-rw-r--r--src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-58856-1.rs8
-rw-r--r--src/test/ui/parser/issues/issue-58856-1.stderr29
-rw-r--r--src/test/ui/parser/issues/issue-58856-2.rs14
-rw-r--r--src/test/ui/parser/issues/issue-58856-2.stderr34
-rw-r--r--src/test/ui/parser/issues/issue-59418.rs18
-rw-r--r--src/test/ui/parser/issues/issue-59418.stderr26
-rw-r--r--src/test/ui/parser/issues/issue-60075.rs11
-rw-r--r--src/test/ui/parser/issues/issue-60075.stderr29
-rw-r--r--src/test/ui/parser/issues/issue-62524.rs6
-rw-r--r--src/test/ui/parser/issues/issue-62524.stderr33
-rw-r--r--src/test/ui/parser/issues/issue-62546.rs3
-rw-r--r--src/test/ui/parser/issues/issue-62546.stderr17
-rw-r--r--src/test/ui/parser/issues/issue-62554.rs6
-rw-r--r--src/test/ui/parser/issues/issue-62554.stderr73
-rw-r--r--src/test/ui/parser/issues/issue-62660.rs11
-rw-r--r--src/test/ui/parser/issues/issue-62660.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-62881.rs6
-rw-r--r--src/test/ui/parser/issues/issue-62881.stderr26
-rw-r--r--src/test/ui/parser/issues/issue-62894.rs7
-rw-r--r--src/test/ui/parser/issues/issue-62894.stderr52
-rw-r--r--src/test/ui/parser/issues/issue-62895.rs11
-rw-r--r--src/test/ui/parser/issues/issue-62895.stderr47
-rw-r--r--src/test/ui/parser/issues/issue-62913.rs4
-rw-r--r--src/test/ui/parser/issues/issue-62913.stderr22
-rw-r--r--src/test/ui/parser/issues/issue-62973.rs8
-rw-r--r--src/test/ui/parser/issues/issue-62973.stderr83
-rw-r--r--src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs22
-rw-r--r--src/test/ui/parser/issues/issue-63116.rs3
-rw-r--r--src/test/ui/parser/issues/issue-63116.stderr24
-rw-r--r--src/test/ui/parser/issues/issue-63135.rs3
-rw-r--r--src/test/ui/parser/issues/issue-63135.stderr43
-rw-r--r--src/test/ui/parser/issues/issue-64732.rs9
-rw-r--r--src/test/ui/parser/issues/issue-64732.stderr24
-rw-r--r--src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs28
-rw-r--r--src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs28
-rw-r--r--src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs26
-rw-r--r--src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr49
-rw-r--r--src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs21
-rw-r--r--src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr67
-rw-r--r--src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs15
-rw-r--r--src/test/ui/parser/issues/issue-6610.rs3
-rw-r--r--src/test/ui/parser/issues/issue-6610.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs14
-rw-r--r--src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-66473.rsbin0 -> 127 bytes
-rw-r--r--src/test/ui/parser/issues/issue-66473.stderrbin0 -> 5260 bytes
-rw-r--r--src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed14
-rw-r--r--src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs14
-rw-r--r--src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr20
-rw-r--r--src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs35
-rw-r--r--src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr128
-rw-r--r--src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs6
-rw-r--r--src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr17
-rw-r--r--src/test/ui/parser/issues/issue-68629.rsbin0 -> 336 bytes
-rw-r--r--src/test/ui/parser/issues/issue-68629.stderrbin0 -> 1831 bytes
-rw-r--r--src/test/ui/parser/issues/issue-68730.rsbin0 -> 175 bytes
-rw-r--r--src/test/ui/parser/issues/issue-68730.stderrbin0 -> 1226 bytes
-rw-r--r--src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs21
-rw-r--r--src/test/ui/parser/issues/issue-68890-2.rs5
-rw-r--r--src/test/ui/parser/issues/issue-68890-2.stderr15
-rw-r--r--src/test/ui/parser/issues/issue-68890.rs4
-rw-r--r--src/test/ui/parser/issues/issue-68890.stderr20
-rw-r--r--src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs16
-rw-r--r--src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs7
-rw-r--r--src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr29
-rw-r--r--src/test/ui/parser/issues/issue-70388-without-witness.fixed9
-rw-r--r--src/test/ui/parser/issues/issue-70388-without-witness.rs9
-rw-r--r--src/test/ui/parser/issues/issue-70388-without-witness.stderr20
-rw-r--r--src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs18
-rw-r--r--src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr56
-rw-r--r--src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs3
-rw-r--r--src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs20
-rw-r--r--src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs14
-rw-r--r--src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-7222.rs12
-rw-r--r--src/test/ui/parser/issues/issue-72253.rs6
-rw-r--r--src/test/ui/parser/issues/issue-72253.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-72373.rs9
-rw-r--r--src/test/ui/parser/issues/issue-72373.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs19
-rw-r--r--src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr39
-rw-r--r--src/test/ui/parser/issues/issue-75599.rs24
-rw-r--r--src/test/ui/parser/issues/issue-76437-async.rs7
-rw-r--r--src/test/ui/parser/issues/issue-76437-async.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs7
-rw-r--r--src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-76437-const-async.rs7
-rw-r--r--src/test/ui/parser/issues/issue-76437-const-async.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-76437-const.rs7
-rw-r--r--src/test/ui/parser/issues/issue-76437-const.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs7
-rw-r--r--src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-76437-unsafe.rs7
-rw-r--r--src/test/ui/parser/issues/issue-76437-unsafe.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-76597.fixed11
-rw-r--r--src/test/ui/parser/issues/issue-76597.rs11
-rw-r--r--src/test/ui/parser/issues/issue-76597.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-7970b.rs4
-rw-r--r--src/test/ui/parser/issues/issue-7970b.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-81806.rs5
-rw-r--r--src/test/ui/parser/issues/issue-81806.stderr17
-rw-r--r--src/test/ui/parser/issues/issue-83639.rs6
-rw-r--r--src/test/ui/parser/issues/issue-83639.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-84104.rs3
-rw-r--r--src/test/ui/parser/issues/issue-84104.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-84117.rs9
-rw-r--r--src/test/ui/parser/issues/issue-84117.stderr72
-rw-r--r--src/test/ui/parser/issues/issue-84148-1.rs3
-rw-r--r--src/test/ui/parser/issues/issue-84148-1.stderr19
-rw-r--r--src/test/ui/parser/issues/issue-84148-2.rs3
-rw-r--r--src/test/ui/parser/issues/issue-84148-2.stderr27
-rw-r--r--src/test/ui/parser/issues/issue-8537.rs5
-rw-r--r--src/test/ui/parser/issues/issue-8537.stderr11
-rw-r--r--src/test/ui/parser/issues/issue-86895.rs3
-rw-r--r--src/test/ui/parser/issues/issue-86895.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-87086-colon-path-sep.rs79
-rw-r--r--src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr90
-rw-r--r--src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed10
-rw-r--r--src/test/ui/parser/issues/issue-87197-missing-semicolon.rs10
-rw-r--r--src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr26
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs9
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr17
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs14
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs14
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs14
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs14
-rw-r--r--src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-87635.rs9
-rw-r--r--src/test/ui/parser/issues/issue-87635.stderr19
-rw-r--r--src/test/ui/parser/issues/issue-87812-path.rs11
-rw-r--r--src/test/ui/parser/issues/issue-87812-path.stderr16
-rw-r--r--src/test/ui/parser/issues/issue-87812.rs13
-rw-r--r--src/test/ui/parser/issues/issue-87812.stderr22
-rw-r--r--src/test/ui/parser/issues/issue-88276-unary-plus.fixed8
-rw-r--r--src/test/ui/parser/issues/issue-88276-unary-plus.rs8
-rw-r--r--src/test/ui/parser/issues/issue-88276-unary-plus.stderr50
-rw-r--r--src/test/ui/parser/issues/issue-88583-union-as-ident.rs15
-rw-r--r--src/test/ui/parser/issues/issue-88770.rs11
-rw-r--r--src/test/ui/parser/issues/issue-88770.stderr60
-rw-r--r--src/test/ui/parser/issues/issue-88818.rs10
-rw-r--r--src/test/ui/parser/issues/issue-88818.stderr18
-rw-r--r--src/test/ui/parser/issues/issue-89388.rs7
-rw-r--r--src/test/ui/parser/issues/issue-89388.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-89396.fixed16
-rw-r--r--src/test/ui/parser/issues/issue-89396.rs16
-rw-r--r--src/test/ui/parser/issues/issue-89396.stderr20
-rw-r--r--src/test/ui/parser/issues/issue-89574.rs4
-rw-r--r--src/test/ui/parser/issues/issue-89574.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs15
-rw-r--r--src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr18
-rw-r--r--src/test/ui/parser/issues/issue-90993.rs6
-rw-r--r--src/test/ui/parser/issues/issue-90993.stderr31
-rw-r--r--src/test/ui/parser/issues/issue-91461.rs6
-rw-r--r--src/test/ui/parser/issues/issue-91461.stderr31
-rw-r--r--src/test/ui/parser/issues/issue-93282.rs15
-rw-r--r--src/test/ui/parser/issues/issue-93282.stderr25
-rw-r--r--src/test/ui/parser/issues/issue-93867.rs10
-rw-r--r--src/test/ui/parser/issues/issue-93867.stderr13
-rw-r--r--src/test/ui/parser/issues/issue-94340.rs8
-rw-r--r--src/test/ui/parser/issues/issue-94340.stderr20
-rw-r--r--src/test/ui/parser/item-free-const-no-body-semantic-fail.rs7
-rw-r--r--src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr24
-rw-r--r--src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs8
-rw-r--r--src/test/ui/parser/item-free-static-no-body-semantic-fail.rs11
-rw-r--r--src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr46
-rw-r--r--src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs8
-rw-r--r--src/test/ui/parser/item-free-type-bounds-semantic-fail.rs20
-rw-r--r--src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr67
-rw-r--r--src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs13
-rw-r--r--src/test/ui/parser/keyword-abstract.rs3
-rw-r--r--src/test/ui/parser/keyword-abstract.stderr13
-rw-r--r--src/test/ui/parser/keyword-as-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-as-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-box-as-identifier.rs10
-rw-r--r--src/test/ui/parser/keyword-box-as-identifier.stderr66
-rw-r--r--src/test/ui/parser/keyword-break-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-break-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-const-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-const-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-continue-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-continue-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-else-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-else-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-enum-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-enum-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-final.rs3
-rw-r--r--src/test/ui/parser/keyword-final.stderr13
-rw-r--r--src/test/ui/parser/keyword-fn-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-fn-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-for-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-for-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-if-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-if-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-impl-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-impl-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-in-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-in-as-identifier.stderr8
-rw-r--r--src/test/ui/parser/keyword-let-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-let-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-loop-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-loop-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-match-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-match-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-mod-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-mod-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-move-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-move-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-mut-as-identifier.rs3
-rw-r--r--src/test/ui/parser/keyword-mut-as-identifier.stderr8
-rw-r--r--src/test/ui/parser/keyword-override.rs3
-rw-r--r--src/test/ui/parser/keyword-override.stderr13
-rw-r--r--src/test/ui/parser/keyword-pub-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-pub-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-ref-as-identifier.rs3
-rw-r--r--src/test/ui/parser/keyword-ref-as-identifier.stderr8
-rw-r--r--src/test/ui/parser/keyword-return-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-return-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-static-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-static-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-struct-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-struct-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-trait-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-trait-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-try-as-identifier-edition2018.rs5
-rw-r--r--src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr13
-rw-r--r--src/test/ui/parser/keyword-type-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-type-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-typeof.rs3
-rw-r--r--src/test/ui/parser/keyword-typeof.stderr13
-rw-r--r--src/test/ui/parser/keyword-unsafe-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-unsafe-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-use-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-use-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-where-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-where-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword-while-as-identifier.rs5
-rw-r--r--src/test/ui/parser/keyword-while-as-identifier.stderr13
-rw-r--r--src/test/ui/parser/keyword.rs5
-rw-r--r--src/test/ui/parser/keyword.stderr13
-rw-r--r--src/test/ui/parser/keywords-followed-by-double-colon.rs8
-rw-r--r--src/test/ui/parser/keywords-followed-by-double-colon.stderr14
-rw-r--r--src/test/ui/parser/labeled-no-colon-expr.rs17
-rw-r--r--src/test/ui/parser/labeled-no-colon-expr.stderr95
-rw-r--r--src/test/ui/parser/let-binop.fixed10
-rw-r--r--src/test/ui/parser/let-binop.rs10
-rw-r--r--src/test/ui/parser/let-binop.stderr26
-rw-r--r--src/test/ui/parser/lifetime-in-pattern-recover.rs6
-rw-r--r--src/test/ui/parser/lifetime-in-pattern-recover.stderr23
-rw-r--r--src/test/ui/parser/lifetime-in-pattern.rs7
-rw-r--r--src/test/ui/parser/lifetime-in-pattern.stderr28
-rw-r--r--src/test/ui/parser/lifetime-semicolon.fixed10
-rw-r--r--src/test/ui/parser/lifetime-semicolon.rs10
-rw-r--r--src/test/ui/parser/lifetime-semicolon.stderr13
-rw-r--r--src/test/ui/parser/lifetime_starts_expressions.rs39
-rw-r--r--src/test/ui/parser/lifetime_starts_expressions.stderr47
-rw-r--r--src/test/ui/parser/macro-bad-delimiter-ident.rs3
-rw-r--r--src/test/ui/parser/macro-bad-delimiter-ident.stderr8
-rw-r--r--src/test/ui/parser/macro-braces-dot-question.rs11
-rw-r--r--src/test/ui/parser/macro-keyword.rs5
-rw-r--r--src/test/ui/parser/macro-keyword.stderr13
-rw-r--r--src/test/ui/parser/macro-mismatched-delim-brace-paren.rs7
-rw-r--r--src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr11
-rw-r--r--src/test/ui/parser/macro-mismatched-delim-paren-brace.rs5
-rw-r--r--src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr22
-rw-r--r--src/test/ui/parser/macro/bad-macro-argument.rs4
-rw-r--r--src/test/ui/parser/macro/bad-macro-argument.stderr8
-rw-r--r--src/test/ui/parser/macro/issue-33569.rs12
-rw-r--r--src/test/ui/parser/macro/issue-33569.stderr30
-rw-r--r--src/test/ui/parser/macro/issue-37113.rs11
-rw-r--r--src/test/ui/parser/macro/issue-37113.stderr13
-rw-r--r--src/test/ui/parser/macro/issue-37234.rs9
-rw-r--r--src/test/ui/parser/macro/issue-37234.stderr13
-rw-r--r--src/test/ui/parser/macro/literals-are-validated-before-expansion.rs10
-rw-r--r--src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr18
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-1.rs9
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-1.stderr14
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-2.rs9
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-2.stderr14
-rw-r--r--src/test/ui/parser/macro/macro-incomplete-parse.rs27
-rw-r--r--src/test/ui/parser/macro/macro-incomplete-parse.stderr35
-rw-r--r--src/test/ui/parser/macro/macro-repeat.rs12
-rw-r--r--src/test/ui/parser/macro/macro-repeat.stderr14
-rw-r--r--src/test/ui/parser/macro/pub-item-macro.rs21
-rw-r--r--src/test/ui/parser/macro/pub-item-macro.stderr31
-rw-r--r--src/test/ui/parser/macro/trait-non-item-macros.rs13
-rw-r--r--src/test/ui/parser/macro/trait-non-item-macros.stderr22
-rw-r--r--src/test/ui/parser/macro/trait-object-macro-matcher.rs14
-rw-r--r--src/test/ui/parser/macro/trait-object-macro-matcher.stderr15
-rw-r--r--src/test/ui/parser/macros-no-semicolon-items.rs15
-rw-r--r--src/test/ui/parser/macros-no-semicolon-items.stderr47
-rw-r--r--src/test/ui/parser/macros-no-semicolon.rs5
-rw-r--r--src/test/ui/parser/macros-no-semicolon.stderr18
-rw-r--r--src/test/ui/parser/match-arm-without-braces.rs87
-rw-r--r--src/test/ui/parser/match-arm-without-braces.stderr131
-rw-r--r--src/test/ui/parser/match-arrows-block-then-binop.rs7
-rw-r--r--src/test/ui/parser/match-arrows-block-then-binop.stderr15
-rw-r--r--src/test/ui/parser/match-refactor-to-expr.fixed12
-rw-r--r--src/test/ui/parser/match-refactor-to-expr.rs12
-rw-r--r--src/test/ui/parser/match-refactor-to-expr.stderr16
-rw-r--r--src/test/ui/parser/mbe_missing_right_paren.rs3
-rw-r--r--src/test/ui/parser/mbe_missing_right_paren.stderr31
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs13
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr34
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs13
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr17
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs12
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr27
-rw-r--r--src/test/ui/parser/mismatched-delim-brace-empty-block.rs5
-rw-r--r--src/test/ui/parser/mismatched-delim-brace-empty-block.stderr14
-rw-r--r--src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs23
-rw-r--r--src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr66
-rw-r--r--src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs11
-rw-r--r--src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr15
-rw-r--r--src/test/ui/parser/missing-semicolon.rs8
-rw-r--r--src/test/ui/parser/missing-semicolon.stderr13
-rw-r--r--src/test/ui/parser/missing_right_paren.rs3
-rw-r--r--src/test/ui/parser/missing_right_paren.stderr32
-rw-r--r--src/test/ui/parser/misspelled-macro-rules.fixed13
-rw-r--r--src/test/ui/parser/misspelled-macro-rules.rs13
-rw-r--r--src/test/ui/parser/misspelled-macro-rules.stderr10
-rw-r--r--src/test/ui/parser/mod_file_not_exist.rs9
-rw-r--r--src/test/ui/parser/mod_file_not_exist.stderr18
-rw-r--r--src/test/ui/parser/mod_file_not_exist_windows.rs9
-rw-r--r--src/test/ui/parser/mod_file_not_exist_windows.stderr18
-rw-r--r--src/test/ui/parser/mod_file_with_path_attr.rs8
-rw-r--r--src/test/ui/parser/mod_file_with_path_attr.stderr8
-rw-r--r--src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs10
-rw-r--r--src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr33
-rw-r--r--src/test/ui/parser/multiline-comment-line-tracking.rs9
-rw-r--r--src/test/ui/parser/multiline-comment-line-tracking.stderr8
-rw-r--r--src/test/ui/parser/multitrait.rs9
-rw-r--r--src/test/ui/parser/multitrait.stderr8
-rw-r--r--src/test/ui/parser/mut-patterns.rs48
-rw-r--r--src/test/ui/parser/mut-patterns.stderr114
-rw-r--r--src/test/ui/parser/nested-missing-closing-angle-bracket.rs4
-rw-r--r--src/test/ui/parser/nested-missing-closing-angle-bracket.stderr8
-rw-r--r--src/test/ui/parser/new-unicode-escapes-1.rs3
-rw-r--r--src/test/ui/parser/new-unicode-escapes-1.stderr13
-rw-r--r--src/test/ui/parser/new-unicode-escapes-2.rs3
-rw-r--r--src/test/ui/parser/new-unicode-escapes-2.stderr8
-rw-r--r--src/test/ui/parser/new-unicode-escapes-3.rs4
-rw-r--r--src/test/ui/parser/new-unicode-escapes-3.stderr18
-rw-r--r--src/test/ui/parser/new-unicode-escapes-4.rs4
-rw-r--r--src/test/ui/parser/new-unicode-escapes-4.stderr8
-rw-r--r--src/test/ui/parser/no-binary-float-literal.rs8
-rw-r--r--src/test/ui/parser/no-binary-float-literal.stderr22
-rw-r--r--src/test/ui/parser/no-const-fn-in-extern-block.rs8
-rw-r--r--src/test/ui/parser/no-const-fn-in-extern-block.stderr29
-rw-r--r--src/test/ui/parser/no-hex-float-literal.rs9
-rw-r--r--src/test/ui/parser/no-hex-float-literal.stderr29
-rw-r--r--src/test/ui/parser/no-unsafe-self.rs14
-rw-r--r--src/test/ui/parser/no-unsafe-self.stderr38
-rw-r--r--src/test/ui/parser/not-a-pred.rs15
-rw-r--r--src/test/ui/parser/not-a-pred.stderr34
-rw-r--r--src/test/ui/parser/nt-parsing-has-recovery.rs10
-rw-r--r--src/test/ui/parser/nt-parsing-has-recovery.stderr29
-rw-r--r--src/test/ui/parser/numeric-lifetime.rs8
-rw-r--r--src/test/ui/parser/numeric-lifetime.stderr23
-rw-r--r--src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs9
-rw-r--r--src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr10
-rw-r--r--src/test/ui/parser/old-suffixes-are-really-forbidden.rs4
-rw-r--r--src/test/ui/parser/old-suffixes-are-really-forbidden.stderr18
-rw-r--r--src/test/ui/parser/omitted-arg-in-item-fn.rs4
-rw-r--r--src/test/ui/parser/omitted-arg-in-item-fn.stderr22
-rw-r--r--src/test/ui/parser/operator-associativity.rs4
-rw-r--r--src/test/ui/parser/paamayim-nekudotayim.rs5
-rw-r--r--src/test/ui/parser/paamayim-nekudotayim.stderr8
-rw-r--r--src/test/ui/parser/parse-assoc-type-lt.rs9
-rw-r--r--src/test/ui/parser/parse-error-correct.rs10
-rw-r--r--src/test/ui/parser/parse-error-correct.stderr33
-rw-r--r--src/test/ui/parser/parse-panic.rs8
-rw-r--r--src/test/ui/parser/parser-recovery-1.rs13
-rw-r--r--src/test/ui/parser/parser-recovery-1.stderr35
-rw-r--r--src/test/ui/parser/parser-recovery-2.rs12
-rw-r--r--src/test/ui/parser/parser-recovery-2.stderr30
-rw-r--r--src/test/ui/parser/parser-unicode-whitespace.rs12
-rw-r--r--src/test/ui/parser/pat-lt-bracket-1.rs7
-rw-r--r--src/test/ui/parser/pat-lt-bracket-1.stderr8
-rw-r--r--src/test/ui/parser/pat-lt-bracket-2.rs4
-rw-r--r--src/test/ui/parser/pat-lt-bracket-2.stderr18
-rw-r--r--src/test/ui/parser/pat-lt-bracket-3.rs14
-rw-r--r--src/test/ui/parser/pat-lt-bracket-3.stderr8
-rw-r--r--src/test/ui/parser/pat-lt-bracket-4.rs11
-rw-r--r--src/test/ui/parser/pat-lt-bracket-4.stderr8
-rw-r--r--src/test/ui/parser/pat-lt-bracket-5.rs3
-rw-r--r--src/test/ui/parser/pat-lt-bracket-5.stderr8
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.rs9
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.stderr18
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.rs9
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.stderr18
-rw-r--r--src/test/ui/parser/pat-ranges-1.rs5
-rw-r--r--src/test/ui/parser/pat-ranges-1.stderr8
-rw-r--r--src/test/ui/parser/pat-ranges-2.rs5
-rw-r--r--src/test/ui/parser/pat-ranges-2.stderr8
-rw-r--r--src/test/ui/parser/pat-ranges-3.rs5
-rw-r--r--src/test/ui/parser/pat-ranges-3.stderr8
-rw-r--r--src/test/ui/parser/pat-ranges-4.rs6
-rw-r--r--src/test/ui/parser/pat-ranges-4.stderr8
-rw-r--r--src/test/ui/parser/pat-ref-enum.rs8
-rw-r--r--src/test/ui/parser/pat-ref-enum.stderr8
-rw-r--r--src/test/ui/parser/pat-tuple-1.rs5
-rw-r--r--src/test/ui/parser/pat-tuple-1.stderr8
-rw-r--r--src/test/ui/parser/pat-tuple-2.rs7
-rw-r--r--src/test/ui/parser/pat-tuple-3.rs6
-rw-r--r--src/test/ui/parser/pat-tuple-3.stderr10
-rw-r--r--src/test/ui/parser/pub-method-macro.rs23
-rw-r--r--src/test/ui/parser/pub-method-macro.stderr10
-rw-r--r--src/test/ui/parser/public-instead-of-pub.fixed8
-rw-r--r--src/test/ui/parser/public-instead-of-pub.rs8
-rw-r--r--src/test/ui/parser/public-instead-of-pub.stderr13
-rw-r--r--src/test/ui/parser/qualified-path-in-turbofish.fixed19
-rw-r--r--src/test/ui/parser/qualified-path-in-turbofish.rs19
-rw-r--r--src/test/ui/parser/qualified-path-in-turbofish.stderr8
-rw-r--r--src/test/ui/parser/range-3.rs6
-rw-r--r--src/test/ui/parser/range-3.stderr8
-rw-r--r--src/test/ui/parser/range-4.rs6
-rw-r--r--src/test/ui/parser/range-4.stderr8
-rw-r--r--src/test/ui/parser/range-inclusive-extra-equals.rs10
-rw-r--r--src/test/ui/parser/range-inclusive-extra-equals.stderr10
-rw-r--r--src/test/ui/parser/range_inclusive.fixed7
-rw-r--r--src/test/ui/parser/range_inclusive.rs7
-rw-r--r--src/test/ui/parser/range_inclusive.stderr11
-rw-r--r--src/test/ui/parser/range_inclusive_dotdotdot.rs23
-rw-r--r--src/test/ui/parser/range_inclusive_dotdotdot.stderr62
-rw-r--r--src/test/ui/parser/ranges-precedence.rs52
-rw-r--r--src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs5
-rw-r--r--src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr9
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-eof.rs3
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-eof.stderr13
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.rs7
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.stderr20
-rw-r--r--src/test/ui/parser/raw/raw-literal-keywords.rs25
-rw-r--r--src/test/ui/parser/raw/raw-literal-keywords.stderr39
-rw-r--r--src/test/ui/parser/raw/raw-literal-self.rs4
-rw-r--r--src/test/ui/parser/raw/raw-literal-self.stderr8
-rw-r--r--src/test/ui/parser/raw/raw-literal-underscore.rs4
-rw-r--r--src/test/ui/parser/raw/raw-literal-underscore.stderr8
-rw-r--r--src/test/ui/parser/raw/raw-str-delim.rs3
-rw-r--r--src/test/ui/parser/raw/raw-str-delim.stderr8
-rw-r--r--src/test/ui/parser/raw/raw-str-in-macro-call.rs14
-rw-r--r--src/test/ui/parser/raw/raw-str-unbalanced.rs22
-rw-r--r--src/test/ui/parser/raw/raw-str-unbalanced.stderr36
-rw-r--r--src/test/ui/parser/raw/raw-str-unterminated.rs4
-rw-r--r--src/test/ui/parser/raw/raw-str-unterminated.stderr11
-rw-r--r--src/test/ui/parser/raw/raw-string-2.rs4
-rw-r--r--src/test/ui/parser/raw/raw-string-2.stderr11
-rw-r--r--src/test/ui/parser/raw/raw-string.rs4
-rw-r--r--src/test/ui/parser/raw/raw-string.stderr13
-rw-r--r--src/test/ui/parser/recover-assoc-const-constraint.rs9
-rw-r--r--src/test/ui/parser/recover-assoc-const-constraint.stderr21
-rw-r--r--src/test/ui/parser/recover-assoc-eq-missing-term.rs6
-rw-r--r--src/test/ui/parser/recover-assoc-eq-missing-term.stderr18
-rw-r--r--src/test/ui/parser/recover-assoc-lifetime-constraint.rs6
-rw-r--r--src/test/ui/parser/recover-assoc-lifetime-constraint.stderr12
-rw-r--r--src/test/ui/parser/recover-const-async-fn-ptr.rs25
-rw-r--r--src/test/ui/parser/recover-const-async-fn-ptr.stderr155
-rw-r--r--src/test/ui/parser/recover-enum.rs11
-rw-r--r--src/test/ui/parser/recover-enum.stderr37
-rw-r--r--src/test/ui/parser/recover-enum2.rs28
-rw-r--r--src/test/ui/parser/recover-enum2.stderr14
-rw-r--r--src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs6
-rw-r--r--src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr11
-rw-r--r--src/test/ui/parser/recover-field-extra-angle-brackets.rs14
-rw-r--r--src/test/ui/parser/recover-field-extra-angle-brackets.stderr8
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.rs15
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.stderr27
-rw-r--r--src/test/ui/parser/recover-from-bad-variant.rs15
-rw-r--r--src/test/ui/parser/recover-from-bad-variant.stderr40
-rw-r--r--src/test/ui/parser/recover-from-homoglyph.rs4
-rw-r--r--src/test/ui/parser/recover-from-homoglyph.stderr22
-rw-r--r--src/test/ui/parser/recover-labeled-non-block-expr.fixed27
-rw-r--r--src/test/ui/parser/recover-labeled-non-block-expr.rs27
-rw-r--r--src/test/ui/parser/recover-labeled-non-block-expr.stderr74
-rw-r--r--src/test/ui/parser/recover-missing-semi.rs13
-rw-r--r--src/test/ui/parser/recover-missing-semi.stderr37
-rw-r--r--src/test/ui/parser/recover-quantified-closure.rs12
-rw-r--r--src/test/ui/parser/recover-quantified-closure.stderr37
-rw-r--r--src/test/ui/parser/recover-range-pats.rs160
-rw-r--r--src/test/ui/parser/recover-range-pats.stderr484
-rw-r--r--src/test/ui/parser/recover-ref-dyn-mut.rs9
-rw-r--r--src/test/ui/parser/recover-ref-dyn-mut.stderr15
-rw-r--r--src/test/ui/parser/recover-struct.rs7
-rw-r--r--src/test/ui/parser/recover-struct.stderr10
-rw-r--r--src/test/ui/parser/recover-tuple-pat.rs12
-rw-r--r--src/test/ui/parser/recover-tuple-pat.stderr8
-rw-r--r--src/test/ui/parser/recover-tuple.rs11
-rw-r--r--src/test/ui/parser/recover-tuple.stderr17
-rw-r--r--src/test/ui/parser/recovered-struct-variant.rs13
-rw-r--r--src/test/ui/parser/recovered-struct-variant.stderr8
-rw-r--r--src/test/ui/parser/regions-out-of-scope-slice.rs11
-rw-r--r--src/test/ui/parser/regions-out-of-scope-slice.stderr11
-rw-r--r--src/test/ui/parser/removed-syntax-closure-lifetime.rs2
-rw-r--r--src/test/ui/parser/removed-syntax-closure-lifetime.stderr13
-rw-r--r--src/test/ui/parser/removed-syntax-enum-newtype.rs1
-rw-r--r--src/test/ui/parser/removed-syntax-enum-newtype.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-field-let.rs6
-rw-r--r--src/test/ui/parser/removed-syntax-field-let.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-field-semicolon.rs6
-rw-r--r--src/test/ui/parser/removed-syntax-field-semicolon.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-fixed-vec.rs1
-rw-r--r--src/test/ui/parser/removed-syntax-fixed-vec.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-fn-sigil.rs3
-rw-r--r--src/test/ui/parser/removed-syntax-fn-sigil.stderr10
-rw-r--r--src/test/ui/parser/removed-syntax-mode.rs4
-rw-r--r--src/test/ui/parser/removed-syntax-mode.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-mut-vec-expr.rs3
-rw-r--r--src/test/ui/parser/removed-syntax-mut-vec-expr.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-mut-vec-ty.rs1
-rw-r--r--src/test/ui/parser/removed-syntax-mut-vec-ty.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-ptr-lifetime.rs1
-rw-r--r--src/test/ui/parser/removed-syntax-ptr-lifetime.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-record.rs1
-rw-r--r--src/test/ui/parser/removed-syntax-record.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-static-fn.rs10
-rw-r--r--src/test/ui/parser/removed-syntax-static-fn.stderr25
-rw-r--r--src/test/ui/parser/removed-syntax-uniq-mut-expr.rs3
-rw-r--r--src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-uniq-mut-ty.rs2
-rw-r--r--src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr8
-rw-r--r--src/test/ui/parser/removed-syntax-with-1.rs10
-rw-r--r--src/test/ui/parser/removed-syntax-with-1.stderr11
-rw-r--r--src/test/ui/parser/removed-syntax-with-2.rs11
-rw-r--r--src/test/ui/parser/removed-syntax-with-2.stderr17
-rw-r--r--src/test/ui/parser/require-parens-for-chained-comparison.rs36
-rw-r--r--src/test/ui/parser/require-parens-for-chained-comparison.stderr100
-rw-r--r--src/test/ui/parser/self-in-function-arg.rs3
-rw-r--r--src/test/ui/parser/self-in-function-arg.stderr8
-rw-r--r--src/test/ui/parser/self-param-semantic-fail.rs64
-rw-r--r--src/test/ui/parser/self-param-semantic-fail.stderr220
-rw-r--r--src/test/ui/parser/self-param-syntactic-pass.rs66
-rw-r--r--src/test/ui/parser/several-carriage-returns-in-doc-comment.rs10
-rw-r--r--src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr20
-rw-r--r--src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs2
-rw-r--r--src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr8
-rw-r--r--src/test/ui/parser/shebang/multiline-attrib.rs7
-rw-r--r--src/test/ui/parser/shebang/regular-attrib.rs5
-rw-r--r--src/test/ui/parser/shebang/shebang-and-attrib.rs9
-rw-r--r--src/test/ui/parser/shebang/shebang-comment.rs6
-rw-r--r--src/test/ui/parser/shebang/shebang-doc-comment.rs3
-rw-r--r--src/test/ui/parser/shebang/shebang-doc-comment.stderr8
-rw-r--r--src/test/ui/parser/shebang/shebang-empty.rs4
-rw-r--r--src/test/ui/parser/shebang/shebang-must-start-file.rs6
-rw-r--r--src/test/ui/parser/shebang/shebang-must-start-file.stderr8
-rw-r--r--src/test/ui/parser/shebang/shebang-space.rs5
-rw-r--r--src/test/ui/parser/shebang/sneaky-attrib.rs16
-rw-r--r--src/test/ui/parser/shebang/valid-shebang.rs6
-rw-r--r--src/test/ui/parser/similar-tokens.rs11
-rw-r--r--src/test/ui/parser/similar-tokens.stderr11
-rw-r--r--src/test/ui/parser/stmt_expr_attrs_placement.rs38
-rw-r--r--src/test/ui/parser/stmt_expr_attrs_placement.stderr65
-rw-r--r--src/test/ui/parser/stripped-nested-outline-mod-pass.rs13
-rw-r--r--src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed35
-rw-r--r--src/test/ui/parser/struct-default-values-and-missing-field-separator.rs35
-rw-r--r--src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr92
-rw-r--r--src/test/ui/parser/struct-field-numeric-shorthand.rs9
-rw-r--r--src/test/ui/parser/struct-field-numeric-shorthand.stderr33
-rw-r--r--src/test/ui/parser/struct-literal-in-for.rs17
-rw-r--r--src/test/ui/parser/struct-literal-in-for.stderr31
-rw-r--r--src/test/ui/parser/struct-literal-in-if.rs17
-rw-r--r--src/test/ui/parser/struct-literal-in-if.stderr18
-rw-r--r--src/test/ui/parser/struct-literal-in-match-discriminant.rs13
-rw-r--r--src/test/ui/parser/struct-literal-in-match-discriminant.stderr18
-rw-r--r--src/test/ui/parser/struct-literal-in-match-guard.rs18
-rw-r--r--src/test/ui/parser/struct-literal-in-while.rs17
-rw-r--r--src/test/ui/parser/struct-literal-in-while.stderr18
-rw-r--r--src/test/ui/parser/struct-literal-restrictions-in-lamda.rs17
-rw-r--r--src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr37
-rw-r--r--src/test/ui/parser/struct-literal-variant-in-if.rs25
-rw-r--r--src/test/ui/parser/struct-literal-variant-in-if.stderr76
-rw-r--r--src/test/ui/parser/suggest-semi-in-array.rs5
-rw-r--r--src/test/ui/parser/suggest-semi-in-array.stderr10
-rw-r--r--src/test/ui/parser/tag-variant-disr-non-nullary.rs12
-rw-r--r--src/test/ui/parser/tag-variant-disr-non-nullary.stderr25
-rw-r--r--src/test/ui/parser/trailing-carriage-return-in-string.rs14
-rw-r--r--src/test/ui/parser/trailing-carriage-return-in-string.stderr10
-rw-r--r--src/test/ui/parser/trailing-plus-in-bounds.rs9
-rw-r--r--src/test/ui/parser/trailing-question-in-macro-type.rs14
-rw-r--r--src/test/ui/parser/trailing-question-in-macro-type.stderr9
-rw-r--r--src/test/ui/parser/trailing-question-in-type.fixed10
-rw-r--r--src/test/ui/parser/trailing-question-in-type.rs10
-rw-r--r--src/test/ui/parser/trailing-question-in-type.stderr24
-rw-r--r--src/test/ui/parser/trait-bounds-not-on-impl.rs7
-rw-r--r--src/test/ui/parser/trait-bounds-not-on-impl.stderr8
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs12
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr60
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-pass.rs13
-rw-r--r--src/test/ui/parser/trait-object-bad-parens.rs16
-rw-r--r--src/test/ui/parser/trait-object-bad-parens.stderr27
-rw-r--r--src/test/ui/parser/trait-object-delimiters.rs17
-rw-r--r--src/test/ui/parser/trait-object-delimiters.stderr78
-rw-r--r--src/test/ui/parser/trait-object-lifetime-parens.rs13
-rw-r--r--src/test/ui/parser/trait-object-lifetime-parens.stderr20
-rw-r--r--src/test/ui/parser/trait-object-polytrait-priority.rs10
-rw-r--r--src/test/ui/parser/trait-object-polytrait-priority.stderr9
-rw-r--r--src/test/ui/parser/trait-object-trait-parens.rs23
-rw-r--r--src/test/ui/parser/trait-object-trait-parens.stderr97
-rw-r--r--src/test/ui/parser/trait-plusequal-splitting.rs8
-rw-r--r--src/test/ui/parser/trait-pub-assoc-const.rs6
-rw-r--r--src/test/ui/parser/trait-pub-assoc-const.stderr9
-rw-r--r--src/test/ui/parser/trait-pub-assoc-ty.rs6
-rw-r--r--src/test/ui/parser/trait-pub-assoc-ty.stderr9
-rw-r--r--src/test/ui/parser/trait-pub-method.rs6
-rw-r--r--src/test/ui/parser/trait-pub-method.stderr9
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.fixed30
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.rs30
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.stderr42
-rw-r--r--src/test/ui/parser/type-alias-where.rs13
-rw-r--r--src/test/ui/parser/type-alias-where.stderr18
-rw-r--r--src/test/ui/parser/type-parameters-in-field-exprs.rs17
-rw-r--r--src/test/ui/parser/type-parameters-in-field-exprs.stderr20
-rw-r--r--src/test/ui/parser/unbalanced-doublequote.rs6
-rw-r--r--src/test/ui/parser/unbalanced-doublequote.stderr10
-rw-r--r--src/test/ui/parser/unclosed-braces.rs22
-rw-r--r--src/test/ui/parser/unclosed-braces.stderr17
-rw-r--r--src/test/ui/parser/unclosed-delimiter-in-dep.rs6
-rw-r--r--src/test/ui/parser/unclosed-delimiter-in-dep.stderr25
-rw-r--r--src/test/ui/parser/unclosed_delim_mod.rs8
-rw-r--r--src/test/ui/parser/unclosed_delim_mod.stderr13
-rw-r--r--src/test/ui/parser/underscore-suffix-for-float.rs4
-rw-r--r--src/test/ui/parser/underscore-suffix-for-float.stderr15
-rw-r--r--src/test/ui/parser/underscore-suffix-for-string.rs8
-rw-r--r--src/test/ui/parser/underscore-suffix-for-string.stderr11
-rw-r--r--src/test/ui/parser/underscore_item_not_const.rs16
-rw-r--r--src/test/ui/parser/underscore_item_not_const.stderr74
-rw-r--r--src/test/ui/parser/unicode-character-literal.fixed21
-rw-r--r--src/test/ui/parser/unicode-character-literal.rs21
-rw-r--r--src/test/ui/parser/unicode-character-literal.stderr48
-rw-r--r--src/test/ui/parser/unicode-chars.rs5
-rw-r--r--src/test/ui/parser/unicode-chars.stderr13
-rw-r--r--src/test/ui/parser/unicode-control-codepoints.rs39
-rw-r--r--src/test/ui/parser/unicode-control-codepoints.stderr192
-rw-r--r--src/test/ui/parser/unicode-quote-chars.rs8
-rw-r--r--src/test/ui/parser/unicode-quote-chars.stderr30
-rw-r--r--src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs11
-rw-r--r--src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr8
-rw-r--r--src/test/ui/parser/unmatched-langle-1.rs9
-rw-r--r--src/test/ui/parser/unmatched-langle-1.stderr22
-rw-r--r--src/test/ui/parser/unmatched-langle-2.rs15
-rw-r--r--src/test/ui/parser/unmatched-langle-2.stderr8
-rw-r--r--src/test/ui/parser/unsafe-foreign-mod-2.rs8
-rw-r--r--src/test/ui/parser/unsafe-foreign-mod-2.stderr28
-rw-r--r--src/test/ui/parser/unsafe-foreign-mod.rs5
-rw-r--r--src/test/ui/parser/unsafe-foreign-mod.stderr8
-rw-r--r--src/test/ui/parser/unsafe-mod.rs9
-rw-r--r--src/test/ui/parser/unsafe-mod.stderr23
-rw-r--r--src/test/ui/parser/unsized.rs7
-rw-r--r--src/test/ui/parser/unsized.stderr8
-rw-r--r--src/test/ui/parser/unsized2.rs7
-rw-r--r--src/test/ui/parser/unsized2.stderr8
-rw-r--r--src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs2
-rw-r--r--src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr14
-rw-r--r--src/test/ui/parser/use-ends-with-mod-sep.rs1
-rw-r--r--src/test/ui/parser/use-ends-with-mod-sep.stderr8
-rw-r--r--src/test/ui/parser/use-unclosed-brace.rs12
-rw-r--r--src/test/ui/parser/use-unclosed-brace.stderr27
-rw-r--r--src/test/ui/parser/utf16-be-without-bom.rsbin0 -> 125 bytes
-rw-r--r--src/test/ui/parser/utf16-be-without-bom.stderrbin0 -> 3537 bytes
-rw-r--r--src/test/ui/parser/utf16-le-without-bom.rsbin0 -> 126 bytes
-rw-r--r--src/test/ui/parser/utf16-le-without-bom.stderrbin0 -> 3500 bytes
-rw-r--r--src/test/ui/parser/utf8_idents-rpass.rs39
-rw-r--r--src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs9
-rw-r--r--src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr24
-rw-r--r--src/test/ui/parser/variadic-ffi-semantic-restrictions.rs77
-rw-r--r--src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr206
-rw-r--r--src/test/ui/parser/variadic-ffi-syntactic-pass.rs53
-rw-r--r--src/test/ui/parser/virtual-structs.rs10
-rw-r--r--src/test/ui/parser/virtual-structs.stderr8
-rw-r--r--src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs15
-rw-r--r--src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr8
-rw-r--r--src/test/ui/parser/where_with_bound.rs5
-rw-r--r--src/test/ui/parser/where_with_bound.stderr15
-rw-r--r--src/test/ui/parser/while-if-let-without-body.rs13
-rw-r--r--src/test/ui/parser/while-if-let-without-body.stderr18
-rw-r--r--src/test/ui/parser/wrong-escape-of-curly-braces.rs8
-rw-r--r--src/test/ui/parser/wrong-escape-of-curly-braces.stderr18
1138 files changed, 23500 insertions, 0 deletions
diff --git a/src/test/ui/parser/ascii-only-character-escape.rs b/src/test/ui/parser/ascii-only-character-escape.rs
new file mode 100644
index 000000000..725c8ad23
--- /dev/null
+++ b/src/test/ui/parser/ascii-only-character-escape.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let x = "\x80"; //~ ERROR out of range hex escape
+ let y = "\xff"; //~ ERROR out of range hex escape
+ let z = "\xe2"; //~ ERROR out of range hex escape
+ let a = b"\x00e2"; // ok because byte literal
+}
diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr
new file mode 100644
index 000000000..b599b35f4
--- /dev/null
+++ b/src/test/ui/parser/ascii-only-character-escape.stderr
@@ -0,0 +1,20 @@
+error: out of range hex escape
+ --> $DIR/ascii-only-character-escape.rs:2:14
+ |
+LL | let x = "\x80";
+ | ^^^^ must be a character in the range [\x00-\x7f]
+
+error: out of range hex escape
+ --> $DIR/ascii-only-character-escape.rs:3:14
+ |
+LL | let y = "\xff";
+ | ^^^^ must be a character in the range [\x00-\x7f]
+
+error: out of range hex escape
+ --> $DIR/ascii-only-character-escape.rs:4:14
+ |
+LL | let z = "\xe2";
+ | ^^^^ must be a character in the range [\x00-\x7f]
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/assoc-const-underscore-semantic-fail.rs b/src/test/ui/parser/assoc-const-underscore-semantic-fail.rs
new file mode 100644
index 000000000..d37ce06c5
--- /dev/null
+++ b/src/test/ui/parser/assoc-const-underscore-semantic-fail.rs
@@ -0,0 +1,17 @@
+// Semantically, an associated constant cannot use `_` as a name.
+
+fn main() {}
+
+const _: () = {
+ pub trait A {
+ const _: () = (); //~ ERROR `const` items in this context need a name
+ }
+ impl A for () {
+ const _: () = (); //~ ERROR `const` items in this context need a name
+ //~^ ERROR const `_` is not a member of trait `A`
+ }
+ struct B;
+ impl B {
+ const _: () = (); //~ ERROR `const` items in this context need a name
+ }
+};
diff --git a/src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr b/src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr
new file mode 100644
index 000000000..538bf0ec1
--- /dev/null
+++ b/src/test/ui/parser/assoc-const-underscore-semantic-fail.stderr
@@ -0,0 +1,27 @@
+error: `const` items in this context need a name
+ --> $DIR/assoc-const-underscore-semantic-fail.rs:7:15
+ |
+LL | const _: () = ();
+ | ^ `_` is not a valid name for this `const` item
+
+error: `const` items in this context need a name
+ --> $DIR/assoc-const-underscore-semantic-fail.rs:10:15
+ |
+LL | const _: () = ();
+ | ^ `_` is not a valid name for this `const` item
+
+error: `const` items in this context need a name
+ --> $DIR/assoc-const-underscore-semantic-fail.rs:15:15
+ |
+LL | const _: () = ();
+ | ^ `_` is not a valid name for this `const` item
+
+error[E0438]: const `_` is not a member of trait `A`
+ --> $DIR/assoc-const-underscore-semantic-fail.rs:10:9
+ |
+LL | const _: () = ();
+ | ^^^^^^^^^^^^^^^^^ not a member of trait `A`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0438`.
diff --git a/src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs b/src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs
new file mode 100644
index 000000000..60da408c8
--- /dev/null
+++ b/src/test/ui/parser/assoc-const-underscore-syntactic-pass.rs
@@ -0,0 +1,18 @@
+// All constant items (associated or otherwise) may syntactically use `_` as a name.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+const _: () = {
+ pub trait A {
+ const _: () = ();
+ }
+ impl A for () {
+ const _: () = ();
+ }
+ impl dyn A {
+ const _: () = ();
+ }
+};
diff --git a/src/test/ui/parser/assoc-oddities-1.rs b/src/test/ui/parser/assoc-oddities-1.rs
new file mode 100644
index 000000000..5914805e5
--- /dev/null
+++ b/src/test/ui/parser/assoc-oddities-1.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Z parse-only
+
+fn main() {
+ // following lines below parse and must not fail
+ x = if c { a } else { b }();
+ x = if true { 1 } else { 0 } as *mut _;
+ // however this does not parse and probably should fail to retain compat?
+ // N.B., `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=`
+ // see assoc-oddities-2 and assoc-oddities-3
+ ..if c { a } else { b }[n]; //~ ERROR expected one of
+}
diff --git a/src/test/ui/parser/assoc-oddities-1.stderr b/src/test/ui/parser/assoc-oddities-1.stderr
new file mode 100644
index 000000000..acf71b489
--- /dev/null
+++ b/src/test/ui/parser/assoc-oddities-1.stderr
@@ -0,0 +1,8 @@
+error: expected one of `.`, `;`, `?`, or `}`, found `[`
+ --> $DIR/assoc-oddities-1.rs:10:28
+ |
+LL | ..if c { a } else { b }[n];
+ | ^ expected one of `.`, `;`, `?`, or `}`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/assoc-oddities-2.rs b/src/test/ui/parser/assoc-oddities-2.rs
new file mode 100644
index 000000000..3d35aad74
--- /dev/null
+++ b/src/test/ui/parser/assoc-oddities-2.rs
@@ -0,0 +1,6 @@
+// compile-flags: -Z parse-only
+
+fn main() {
+ // see assoc-oddities-1 for explanation
+ x..if c { a } else { b }[n]; //~ ERROR expected one of
+}
diff --git a/src/test/ui/parser/assoc-oddities-2.stderr b/src/test/ui/parser/assoc-oddities-2.stderr
new file mode 100644
index 000000000..d3b90c34c
--- /dev/null
+++ b/src/test/ui/parser/assoc-oddities-2.stderr
@@ -0,0 +1,8 @@
+error: expected one of `.`, `;`, `?`, or `}`, found `[`
+ --> $DIR/assoc-oddities-2.rs:5:29
+ |
+LL | x..if c { a } else { b }[n];
+ | ^ expected one of `.`, `;`, `?`, or `}`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/assoc-static-semantic-fail.rs b/src/test/ui/parser/assoc-static-semantic-fail.rs
new file mode 100644
index 000000000..a8759d209
--- /dev/null
+++ b/src/test/ui/parser/assoc-static-semantic-fail.rs
@@ -0,0 +1,52 @@
+// Semantically, we do not allow e.g., `static X: u8 = 0;` as an associated item.
+
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+fn main() {}
+
+struct S;
+impl S {
+ static IA: u8 = 0;
+ //~^ ERROR associated `static` items are not allowed
+ static IB: u8;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR associated constant in `impl` without body
+ default static IC: u8 = 0;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR a static item cannot be `default`
+ pub(crate) default static ID: u8;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR associated constant in `impl` without body
+ //~| ERROR a static item cannot be `default`
+}
+
+trait T {
+ static TA: u8 = 0;
+ //~^ ERROR associated `static` items are not allowed
+ static TB: u8;
+ //~^ ERROR associated `static` items are not allowed
+ default static TC: u8 = 0;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR a static item cannot be `default`
+ pub(crate) default static TD: u8;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR unnecessary visibility qualifier
+ //~| ERROR a static item cannot be `default`
+}
+
+impl T for S {
+ static TA: u8 = 0;
+ //~^ ERROR associated `static` items are not allowed
+ static TB: u8;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR associated constant in `impl` without body
+ default static TC: u8 = 0;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR a static item cannot be `default`
+ pub default static TD: u8;
+ //~^ ERROR associated `static` items are not allowed
+ //~| ERROR associated constant in `impl` without body
+ //~| ERROR unnecessary visibility qualifier
+ //~| ERROR a static item cannot be `default`
+}
diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr
new file mode 100644
index 000000000..7ae092cee
--- /dev/null
+++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr
@@ -0,0 +1,177 @@
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:10:5
+ |
+LL | static IA: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:12:5
+ |
+LL | static IB: u8;
+ | ^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-semantic-fail.rs:15:5
+ |
+LL | default static IC: u8 = 0;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:15:5
+ |
+LL | default static IC: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-semantic-fail.rs:18:16
+ |
+LL | pub(crate) default static ID: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:18:5
+ |
+LL | pub(crate) default static ID: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:25:5
+ |
+LL | static TA: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:27:5
+ |
+LL | static TB: u8;
+ | ^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-semantic-fail.rs:29:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:29:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-semantic-fail.rs:32:16
+ |
+LL | pub(crate) default static TD: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:32:5
+ |
+LL | pub(crate) default static TD: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:39:5
+ |
+LL | static TA: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:41:5
+ |
+LL | static TB: u8;
+ | ^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-semantic-fail.rs:44:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:44:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-semantic-fail.rs:47:9
+ |
+LL | pub default static TD: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-semantic-fail.rs:47:5
+ |
+LL | pub default static TD: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: associated constant in `impl` without body
+ --> $DIR/assoc-static-semantic-fail.rs:12:5
+ |
+LL | static IB: u8;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error: associated constant in `impl` without body
+ --> $DIR/assoc-static-semantic-fail.rs:18:5
+ |
+LL | pub(crate) default static ID: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error[E0449]: unnecessary visibility qualifier
+ --> $DIR/assoc-static-semantic-fail.rs:32:5
+ |
+LL | pub(crate) default static TD: u8;
+ | ^^^^^^^^^^
+
+error: associated constant in `impl` without body
+ --> $DIR/assoc-static-semantic-fail.rs:41:5
+ |
+LL | static TB: u8;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error: associated constant in `impl` without body
+ --> $DIR/assoc-static-semantic-fail.rs:47:5
+ |
+LL | pub default static TD: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error[E0449]: unnecessary visibility qualifier
+ --> $DIR/assoc-static-semantic-fail.rs:47:5
+ |
+LL | pub default static TD: u8;
+ | ^^^ `pub` not permitted here because it's implied
+
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/assoc-static-semantic-fail.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+
+error: aborting due to 24 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0449`.
diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.rs b/src/test/ui/parser/assoc-static-syntactic-fail.rs
new file mode 100644
index 000000000..492f2ea16
--- /dev/null
+++ b/src/test/ui/parser/assoc-static-syntactic-fail.rs
@@ -0,0 +1,33 @@
+// Syntactically, we do allow e.g., `static X: u8 = 0;` as an associated item.
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl S {
+ static IA: u8 = 0; //~ ERROR associated `static` items are not allowed
+ static IB: u8; //~ ERROR associated `static` items are not allowed
+ default static IC: u8 = 0; //~ ERROR associated `static` items are not allowed
+ //~^ ERROR a static item cannot be `default`
+ pub(crate) default static ID: u8; //~ ERROR associated `static` items are not allowed
+ //~^ ERROR a static item cannot be `default`
+}
+
+#[cfg(FALSE)]
+trait T {
+ static TA: u8 = 0; //~ ERROR associated `static` items are not allowed
+ static TB: u8; //~ ERROR associated `static` items are not allowed
+ default static TC: u8 = 0; //~ ERROR associated `static` items are not allowed
+ //~^ ERROR a static item cannot be `default`
+ pub(crate) default static TD: u8; //~ ERROR associated `static` items are not allowed
+ //~^ ERROR a static item cannot be `default`
+}
+
+#[cfg(FALSE)]
+impl T for S {
+ static TA: u8 = 0; //~ ERROR associated `static` items are not allowed
+ static TB: u8; //~ ERROR associated `static` items are not allowed
+ default static TC: u8 = 0; //~ ERROR associated `static` items are not allowed
+ //~^ ERROR a static item cannot be `default`
+ pub default static TD: u8; //~ ERROR associated `static` items are not allowed
+ //~^ ERROR a static item cannot be `default`
+}
diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.stderr b/src/test/ui/parser/assoc-static-syntactic-fail.stderr
new file mode 100644
index 000000000..e97236145
--- /dev/null
+++ b/src/test/ui/parser/assoc-static-syntactic-fail.stderr
@@ -0,0 +1,122 @@
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:7:5
+ |
+LL | static IA: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:8:5
+ |
+LL | static IB: u8;
+ | ^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-syntactic-fail.rs:9:5
+ |
+LL | default static IC: u8 = 0;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:9:5
+ |
+LL | default static IC: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-syntactic-fail.rs:11:16
+ |
+LL | pub(crate) default static ID: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:11:5
+ |
+LL | pub(crate) default static ID: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:17:5
+ |
+LL | static TA: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:18:5
+ |
+LL | static TB: u8;
+ | ^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-syntactic-fail.rs:19:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:19:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-syntactic-fail.rs:21:16
+ |
+LL | pub(crate) default static TD: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:21:5
+ |
+LL | pub(crate) default static TD: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:27:5
+ |
+LL | static TA: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:28:5
+ |
+LL | static TB: u8;
+ | ^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-syntactic-fail.rs:29:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:29:5
+ |
+LL | default static TC: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a static item cannot be `default`
+ --> $DIR/assoc-static-syntactic-fail.rs:31:9
+ |
+LL | pub default static TD: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/assoc-static-syntactic-fail.rs:31:5
+ |
+LL | pub default static TD: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 18 previous errors
+
diff --git a/src/test/ui/parser/assoc-type-in-type-arg.rs b/src/test/ui/parser/assoc-type-in-type-arg.rs
new file mode 100644
index 000000000..000956ea2
--- /dev/null
+++ b/src/test/ui/parser/assoc-type-in-type-arg.rs
@@ -0,0 +1,11 @@
+trait Tr {
+ type TrSubtype;
+}
+
+struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> {
+ //~^ ERROR bounds on associated types do not belong here
+ item: Item,
+ item_sub: &'a <Item as Tr>::TrSubtype,
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/assoc-type-in-type-arg.stderr b/src/test/ui/parser/assoc-type-in-type-arg.stderr
new file mode 100644
index 000000000..b637702f2
--- /dev/null
+++ b/src/test/ui/parser/assoc-type-in-type-arg.stderr
@@ -0,0 +1,8 @@
+error: bounds on associated types do not belong here
+ --> $DIR/assoc-type-in-type-arg.rs:5:26
+ |
+LL | struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ belongs in `where` clause
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs
new file mode 100644
index 000000000..b238a9ca2
--- /dev/null
+++ b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.rs
@@ -0,0 +1,16 @@
+// Test you can't use a higher-ranked trait bound inside of a qualified
+// path (just won't parse).
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A)
+ //~^ ERROR expected identifier, found keyword `for`
+ //~| ERROR expected one of `::` or `>`
+{
+}
+
+pub fn main() {}
diff --git a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
new file mode 100644
index 000000000..aa0fa0e3c
--- /dev/null
+++ b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
@@ -0,0 +1,14 @@
+error: expected identifier, found keyword `for`
+ --> $DIR/associated-types-project-from-hrtb-explicit.rs:10:21
+ |
+LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A)
+ | ^^^ expected identifier, found keyword
+
+error: expected one of `::` or `>`, found `Foo`
+ --> $DIR/associated-types-project-from-hrtb-explicit.rs:10:29
+ |
+LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A)
+ | ^^^ expected one of `::` or `>`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/attr-bad-meta-2.rs b/src/test/ui/parser/attr-bad-meta-2.rs
new file mode 100644
index 000000000..db612ed88
--- /dev/null
+++ b/src/test/ui/parser/attr-bad-meta-2.rs
@@ -0,0 +1,2 @@
+#[path =] //~ ERROR expected expression, found `]`
+mod m {}
diff --git a/src/test/ui/parser/attr-bad-meta-2.stderr b/src/test/ui/parser/attr-bad-meta-2.stderr
new file mode 100644
index 000000000..6fc6fb665
--- /dev/null
+++ b/src/test/ui/parser/attr-bad-meta-2.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `]`
+ --> $DIR/attr-bad-meta-2.rs:1:9
+ |
+LL | #[path =]
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr-bad-meta-3.rs b/src/test/ui/parser/attr-bad-meta-3.rs
new file mode 100644
index 000000000..b51e9f221
--- /dev/null
+++ b/src/test/ui/parser/attr-bad-meta-3.rs
@@ -0,0 +1,2 @@
+#[path() token] //~ ERROR expected `]`, found `token`
+mod m {}
diff --git a/src/test/ui/parser/attr-bad-meta-3.stderr b/src/test/ui/parser/attr-bad-meta-3.stderr
new file mode 100644
index 000000000..4fa420c79
--- /dev/null
+++ b/src/test/ui/parser/attr-bad-meta-3.stderr
@@ -0,0 +1,8 @@
+error: expected `]`, found `token`
+ --> $DIR/attr-bad-meta-3.rs:1:10
+ |
+LL | #[path() token]
+ | ^^^^^ expected `]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr-bad-meta.rs b/src/test/ui/parser/attr-bad-meta.rs
new file mode 100644
index 000000000..8001977f5
--- /dev/null
+++ b/src/test/ui/parser/attr-bad-meta.rs
@@ -0,0 +1,2 @@
+#[path*] //~ ERROR expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*`
+mod m {}
diff --git a/src/test/ui/parser/attr-bad-meta.stderr b/src/test/ui/parser/attr-bad-meta.stderr
new file mode 100644
index 000000000..8d65c423c
--- /dev/null
+++ b/src/test/ui/parser/attr-bad-meta.stderr
@@ -0,0 +1,8 @@
+error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*`
+ --> $DIR/attr-bad-meta.rs:1:7
+ |
+LL | #[path*]
+ | ^ expected one of `(`, `::`, `=`, `[`, `]`, or `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr-before-eof.rs b/src/test/ui/parser/attr-before-eof.rs
new file mode 100644
index 000000000..6af1783e6
--- /dev/null
+++ b/src/test/ui/parser/attr-before-eof.rs
@@ -0,0 +1,3 @@
+fn main() {}
+
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/ui/parser/attr-before-eof.stderr b/src/test/ui/parser/attr-before-eof.stderr
new file mode 100644
index 000000000..a2acb9437
--- /dev/null
+++ b/src/test/ui/parser/attr-before-eof.stderr
@@ -0,0 +1,8 @@
+error: expected item after attributes
+ --> $DIR/attr-before-eof.rs:3:1
+ |
+LL | #[derive(Debug)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr-dangling-in-fn.rs b/src/test/ui/parser/attr-dangling-in-fn.rs
new file mode 100644
index 000000000..c7c45bafb
--- /dev/null
+++ b/src/test/ui/parser/attr-dangling-in-fn.rs
@@ -0,0 +1,8 @@
+// error-pattern:expected statement
+
+fn f() {
+ #[foo = "bar"]
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/attr-dangling-in-fn.stderr b/src/test/ui/parser/attr-dangling-in-fn.stderr
new file mode 100644
index 000000000..b1bb3ab3b
--- /dev/null
+++ b/src/test/ui/parser/attr-dangling-in-fn.stderr
@@ -0,0 +1,8 @@
+error: expected statement after outer attribute
+ --> $DIR/attr-dangling-in-fn.rs:4:3
+ |
+LL | #[foo = "bar"]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr-dangling-in-mod.rs b/src/test/ui/parser/attr-dangling-in-mod.rs
new file mode 100644
index 000000000..261ed3913
--- /dev/null
+++ b/src/test/ui/parser/attr-dangling-in-mod.rs
@@ -0,0 +1,6 @@
+// error-pattern:expected item
+
+fn main() {
+}
+
+#[foo = "bar"]
diff --git a/src/test/ui/parser/attr-dangling-in-mod.stderr b/src/test/ui/parser/attr-dangling-in-mod.stderr
new file mode 100644
index 000000000..1c892eac0
--- /dev/null
+++ b/src/test/ui/parser/attr-dangling-in-mod.stderr
@@ -0,0 +1,8 @@
+error: expected item after attributes
+ --> $DIR/attr-dangling-in-mod.rs:6:1
+ |
+LL | #[foo = "bar"]
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs
new file mode 100644
index 000000000..09f494bdc
--- /dev/null
+++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs
@@ -0,0 +1,111 @@
+#![feature(half_open_range_patterns)]
+
+fn main() {}
+
+#[cfg(FALSE)] fn e() { let _ = box #![attr] 0; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = [#[attr]]; }
+//~^ ERROR expected expression, found `]`
+#[cfg(FALSE)] fn e() { let _ = foo#[attr](); }
+//~^ ERROR expected one of
+#[cfg(FALSE)] fn e() { let _ = foo(#![attr]); }
+//~^ ERROR an inner attribute is not permitted in this context
+//~| ERROR expected expression, found `)`
+#[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); }
+//~^ ERROR an inner attribute is not permitted in this context
+//~| ERROR expected expression, found `)`
+#[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = !#![attr] 0; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = -#![attr] 0; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; }
+//~^ ERROR expected one of
+#[cfg(FALSE)] fn e() { let _ = || #![attr] foo; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; }
+//~^ ERROR expected expression, found `..`
+#[cfg(FALSE)] fn e() { let _ = #[attr] ..; }
+//~^ ERROR expected expression, found `..`
+#[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; }
+//~^ ERROR expected one of
+#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; }
+//~^ ERROR expected one of
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; }
+//~^ ERROR an inner attribute is not permitted in this context
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; }
+//~^ ERROR outer attributes are not allowed on `if`
+#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; }
+//~^ ERROR an inner attribute is not permitted in this context
+
+#[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; }
+//~^ ERROR an inner attribute is not permitted following an outer attribute
+#[cfg(FALSE)] fn s() { #[attr] #![attr] 0; }
+//~^ ERROR an inner attribute is not permitted following an outer attribute
+#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
+//~^ ERROR an inner attribute is not permitted following an outer attribute
+#[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
+//~^ ERROR an inner attribute is not permitted following an outer attribute
+#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
+//~^ ERROR an inner attribute is not permitted following an outer attribute
+
+// FIXME: Allow attributes in pattern constexprs?
+// note: requires parens in patterns to allow disambiguation
+
+#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
+//~^ ERROR inclusive range with no end
+//~| ERROR expected one of `=>`, `if`, or `|`, found `#`
+#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
+//~^ ERROR inclusive range with no end
+//~| ERROR expected one of `=>`, `if`, or `|`, found `#`
+#[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } }
+//~^ ERROR unexpected token: `#`
+#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
+//~^ ERROR inclusive range with no end
+//~| ERROR expected one of `=>`, `if`, or `|`, found `#`
+
+#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); }
+//~^ ERROR unexpected token: `#`
+//~| ERROR expected one of `.`
+#[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); }
+//~^ ERROR unexpected token: `#`
+//~| ERROR expected one of `.`
+
+// make sure we don't catch this bug again...
+#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
+//~^ ERROR expected statement after outer attribute
+#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
+//~^ ERROR expected statement after outer attribute
diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr
new file mode 100644
index 000000000..7bb3db030
--- /dev/null
+++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr
@@ -0,0 +1,445 @@
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:5:36
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected expression, found `]`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:7:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = [#[attr]]; }
+ | ^ expected expression
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:9:35
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = foo#[attr](); }
+ | ^ expected one of 8 possible tokens
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:11:36
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected expression, found `)`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:11:44
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); }
+ | ^ expected expression
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:14:38
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected expression, found `)`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:14:46
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); }
+ | ^ expected expression
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:17:36
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:19:33
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:21:33
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:23:34
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; }
+ | ^ expected one of 8 possible tokens
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:25:35
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:27:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:29:35
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:31:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected expression, found `..`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:33:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; }
+ | ^^ expected expression
+
+error: expected expression, found `..`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:35:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; }
+ | ^^ expected expression
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:37:41
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:39:45
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:41:37
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
+ | -- ^^^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `if`
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:43:38
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:45:40
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; }
+ | ^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:47:45
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; }
+ | ---- ^^^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `else`
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:49:46
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:51:45
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
+ | ---- ^^^^^^^ ------- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `else`
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:53:50
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
+ | -- ^^^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `if`
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:55:51
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:57:45
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
+ | -- ^^^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `if`
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:59:46
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:61:48
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; }
+ | ^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:63:53
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; }
+ | ---- ^^^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `else`
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:65:54
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:67:53
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
+ | ---- ^^^^^^^ --------------- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `else`
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/attr-stmt-expr-attr-bad.rs:69:66
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; }
+ | -- ^^^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `if`
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr-stmt-expr-attr-bad.rs:71:67
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; }
+ | ^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted following an outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:74:32
+ |
+LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; }
+ | ------- ^^^^^^^^ not permitted following an outer attribute
+ | |
+ | previous outer attribute
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted following an outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:76:32
+ |
+LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; }
+ | ------- ^^^^^^^^ not permitted following an outer attribute
+ | |
+ | previous outer attribute
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted following an outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:78:32
+ |
+LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
+ | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation
+ | | |
+ | | not permitted following an outer attribute
+ | previous outer attribute
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the item macro invocation, change the attribute from inner to outer style
+ |
+LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
+LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); }
+ |
+
+error: an inner attribute is not permitted following an outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:80:32
+ |
+LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
+ | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation
+ | | |
+ | | not permitted following an outer attribute
+ | previous outer attribute
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the item macro invocation, change the attribute from inner to outer style
+ |
+LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
+LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; }
+ |
+
+error: an inner attribute is not permitted following an outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:82:32
+ |
+LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
+ | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation
+ | | |
+ | | not permitted following an outer attribute
+ | previous outer attribute
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the item macro invocation, change the attribute from inner to outer style
+ |
+LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
+LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; }
+ |
+
+error[E0586]: inclusive range with no end
+ --> $DIR/attr-stmt-expr-attr-bad.rs:88:35
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: expected one of `=>`, `if`, or `|`, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:88:38
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
+ | ^ expected one of `=>`, `if`, or `|`
+
+error[E0586]: inclusive range with no end
+ --> $DIR/attr-stmt-expr-attr-bad.rs:91:35
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: expected one of `=>`, `if`, or `|`, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:91:38
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
+ | ^ expected one of `=>`, `if`, or `|`
+
+error: unexpected token: `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:94:39
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } }
+ | ^
+
+error[E0586]: inclusive range with no end
+ --> $DIR/attr-stmt-expr-attr-bad.rs:96:35
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: expected one of `=>`, `if`, or `|`, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:96:38
+ |
+LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
+ | ^ expected one of `=>`, `if`, or `|`
+
+error: unexpected token: `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:100:34
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); }
+ | ^
+
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:100:34
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); }
+ | ^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: unexpected token: `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:103:34
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); }
+ | ^
+
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#`
+ --> $DIR/attr-stmt-expr-attr-bad.rs:103:34
+ |
+LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); }
+ | ^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: expected statement after outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:108:37
+ |
+LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
+ | ^^^^^^^
+
+error: expected statement after outer attribute
+ --> $DIR/attr-stmt-expr-attr-bad.rs:110:37
+ |
+LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
+ | ^^^^^^^
+
+error: aborting due to 53 previous errors
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/src/test/ui/parser/attr-with-a-semicolon.rs b/src/test/ui/parser/attr-with-a-semicolon.rs
new file mode 100644
index 000000000..56fe40b91
--- /dev/null
+++ b/src/test/ui/parser/attr-with-a-semicolon.rs
@@ -0,0 +1,4 @@
+#[derive(Debug, Clone)]; //~ERROR expected item after attributes
+struct Foo;
+
+fn main() {}
diff --git a/src/test/ui/parser/attr-with-a-semicolon.stderr b/src/test/ui/parser/attr-with-a-semicolon.stderr
new file mode 100644
index 000000000..0de3490b8
--- /dev/null
+++ b/src/test/ui/parser/attr-with-a-semicolon.stderr
@@ -0,0 +1,14 @@
+error: expected item after attributes
+ --> $DIR/attr-with-a-semicolon.rs:1:1
+ |
+LL | #[derive(Debug, Clone)];
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: consider removing this semicolon
+ |
+LL - #[derive(Debug, Clone)];
+LL + #[derive(Debug, Clone)]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attr.rs b/src/test/ui/parser/attr.rs
new file mode 100644
index 000000000..42b2dfde8
--- /dev/null
+++ b/src/test/ui/parser/attr.rs
@@ -0,0 +1,6 @@
+#![feature(lang_items)]
+
+fn main() {}
+
+#![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context
+fn foo() {}
diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr
new file mode 100644
index 000000000..7cd0ac224
--- /dev/null
+++ b/src/test/ui/parser/attr.stderr
@@ -0,0 +1,17 @@
+error: an inner attribute is not permitted in this context
+ --> $DIR/attr.rs:5:1
+ |
+LL | #![lang = "foo"]
+ | ^^^^^^^^^^^^^^^^
+LL | fn foo() {}
+ | ----------- the inner attribute doesn't annotate this function
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the function, change the attribute from inner to outer style
+ |
+LL - #![lang = "foo"]
+LL + #[lang = "foo"]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs
new file mode 100644
index 000000000..c2cc91d8f
--- /dev/null
+++ b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.rs
@@ -0,0 +1,3 @@
+fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters
+
+fn main() {}
diff --git a/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr
new file mode 100644
index 000000000..4c5964715
--- /dev/null
+++ b/src/test/ui/parser/attribute-with-no-generics-in-parameter-list.stderr
@@ -0,0 +1,8 @@
+error: attribute without generic parameters
+ --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8
+ |
+LL | fn foo<#[attr]>() {}
+ | ^^^^^^^ attributes are only permitted when preceding parameters
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/attrs-after-extern-mod.rs b/src/test/ui/parser/attrs-after-extern-mod.rs
new file mode 100644
index 000000000..e3f0fa0fc
--- /dev/null
+++ b/src/test/ui/parser/attrs-after-extern-mod.rs
@@ -0,0 +1,7 @@
+// Make sure there's an error when given `extern { ... #[attr] }`.
+
+fn main() {}
+
+extern "C" {
+ #[cfg(stage37)] //~ ERROR expected item after attributes
+}
diff --git a/src/test/ui/parser/attrs-after-extern-mod.stderr b/src/test/ui/parser/attrs-after-extern-mod.stderr
new file mode 100644
index 000000000..135d98457
--- /dev/null
+++ b/src/test/ui/parser/attrs-after-extern-mod.stderr
@@ -0,0 +1,12 @@
+error: expected item after attributes
+ --> $DIR/attrs-after-extern-mod.rs:6:5
+ |
+LL | extern "C" {
+ | - while parsing this item list starting here
+LL | #[cfg(stage37)]
+ | ^^^^^^^^^^^^^^^
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-char-literals.rs b/src/test/ui/parser/bad-char-literals.rs
new file mode 100644
index 000000000..748b4a222
--- /dev/null
+++ b/src/test/ui/parser/bad-char-literals.rs
@@ -0,0 +1,20 @@
+// ignore-tidy-cr
+// ignore-tidy-tab
+
+fn main() {
+ // these literals are just silly.
+ ''';
+ //~^ ERROR: character constant must be escaped: `'`
+
+ // note that this is a literal "\n" byte
+ '
+';
+ //~^^ ERROR: character constant must be escaped: `\n`
+
+ // note that this is a literal "\r" byte
+ ' '; //~ ERROR: character constant must be escaped: `\r`
+
+ // note that this is a literal tab character here
+ ' ';
+ //~^ ERROR: character constant must be escaped: `\t`
+}
diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr
new file mode 100644
index 000000000..a22ddbac1
--- /dev/null
+++ b/src/test/ui/parser/bad-char-literals.stderr
@@ -0,0 +1,28 @@
+error: character constant must be escaped: `'`
+ --> $DIR/bad-char-literals.rs:6:6
+ |
+LL | ''';
+ | ^ help: escape the character: `\'`
+
+error: character constant must be escaped: `\n`
+ --> $DIR/bad-char-literals.rs:10:6
+ |
+LL | '
+ | ______^
+LL | | ';
+ | |_ help: escape the character: `\n`
+
+error: character constant must be escaped: `\r`
+ --> $DIR/bad-char-literals.rs:15:6
+ |
+LL | ' ';
+ | ^ help: escape the character: `\r`
+
+error: character constant must be escaped: `\t`
+ --> $DIR/bad-char-literals.rs:18:6
+ |
+LL | ' ';
+ | ^^^^ help: escape the character: `\t`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/bad-crate-name.rs b/src/test/ui/parser/bad-crate-name.rs
new file mode 100644
index 000000000..837d5c354
--- /dev/null
+++ b/src/test/ui/parser/bad-crate-name.rs
@@ -0,0 +1,5 @@
+extern crate krate-name-here;
+//~^ ERROR crate name using dashes are not valid in `extern crate` statements
+//~| ERROR can't find crate for `krate_name_here`
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-crate-name.stderr b/src/test/ui/parser/bad-crate-name.stderr
new file mode 100644
index 000000000..c98a620f1
--- /dev/null
+++ b/src/test/ui/parser/bad-crate-name.stderr
@@ -0,0 +1,20 @@
+error: crate name using dashes are not valid in `extern crate` statements
+ --> $DIR/bad-crate-name.rs:1:14
+ |
+LL | extern crate krate-name-here;
+ | ^^^^^^^^^^^^^^^ dash-separated idents are not valid
+ |
+help: if the original crate name uses dashes you need to use underscores in the code
+ |
+LL | extern crate krate_name_here;
+ | ~ ~
+
+error[E0463]: can't find crate for `krate_name_here`
+ --> $DIR/bad-crate-name.rs:1:1
+ |
+LL | extern crate krate-name-here;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0463`.
diff --git a/src/test/ui/parser/bad-escape-suggest-raw-string.rs b/src/test/ui/parser/bad-escape-suggest-raw-string.rs
new file mode 100644
index 000000000..978b92cbc
--- /dev/null
+++ b/src/test/ui/parser/bad-escape-suggest-raw-string.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let ok = r"ab\[c";
+ let bad = "ab\[c";
+ //~^ ERROR unknown character escape: `[`
+ //~| HELP for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals>
+ //~| HELP if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
+}
diff --git a/src/test/ui/parser/bad-escape-suggest-raw-string.stderr b/src/test/ui/parser/bad-escape-suggest-raw-string.stderr
new file mode 100644
index 000000000..fc34bd328
--- /dev/null
+++ b/src/test/ui/parser/bad-escape-suggest-raw-string.stderr
@@ -0,0 +1,14 @@
+error: unknown character escape: `[`
+ --> $DIR/bad-escape-suggest-raw-string.rs:3:19
+ |
+LL | let bad = "ab\[c";
+ | ^ unknown character escape
+ |
+ = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals>
+help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal
+ |
+LL | let bad = r"ab\[c";
+ | ~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.fixed b/src/test/ui/parser/bad-fn-ptr-qualifier.fixed
new file mode 100644
index 000000000..ad8e718cf
--- /dev/null
+++ b/src/test/ui/parser/bad-fn-ptr-qualifier.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+// edition:2018
+// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix.
+
+pub type T0 = fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T1 = extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T2 = unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T3 = fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T4 = extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T5 = unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T6 = unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+pub type FTT0 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT1 = for<'a> extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT2 = for<'a> unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT3 = for<'a> fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT4 = for<'a> extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT5 = for<'a> unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `async`
+pub type FTT6 = for<'a> unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.rs b/src/test/ui/parser/bad-fn-ptr-qualifier.rs
new file mode 100644
index 000000000..c04813dad
--- /dev/null
+++ b/src/test/ui/parser/bad-fn-ptr-qualifier.rs
@@ -0,0 +1,26 @@
+// run-rustfix
+// edition:2018
+// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix.
+
+pub type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T6 = const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+pub type FTT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT5 = for<'a> async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `async`
+pub type FTT6 = for<'a> const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.stderr b/src/test/ui/parser/bad-fn-ptr-qualifier.stderr
new file mode 100644
index 000000000..265e31329
--- /dev/null
+++ b/src/test/ui/parser/bad-fn-ptr-qualifier.stderr
@@ -0,0 +1,146 @@
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:5:15
+ |
+LL | pub type T0 = const fn();
+ | -----^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:6:15
+ |
+LL | pub type T1 = const extern "C" fn();
+ | -----^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:7:15
+ |
+LL | pub type T2 = const unsafe extern fn();
+ | -----^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:8:15
+ |
+LL | pub type T3 = async fn();
+ | -----^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:9:15
+ |
+LL | pub type T4 = async extern fn();
+ | -----^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:10:15
+ |
+LL | pub type T5 = async unsafe extern "C" fn();
+ | -----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:11:15
+ |
+LL | pub type T6 = const async unsafe extern "C" fn();
+ | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:11:15
+ |
+LL | pub type T6 = const async unsafe extern "C" fn();
+ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:15:17
+ |
+LL | pub type FTT0 = for<'a> const fn();
+ | ^^^^^^^^-----^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:16:17
+ |
+LL | pub type FTT1 = for<'a> const extern "C" fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:17:17
+ |
+LL | pub type FTT2 = for<'a> const unsafe extern fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:18:17
+ |
+LL | pub type FTT3 = for<'a> async fn();
+ | ^^^^^^^^-----^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:19:17
+ |
+LL | pub type FTT4 = for<'a> async extern fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:20:17
+ |
+LL | pub type FTT5 = for<'a> async unsafe extern "C" fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/bad-fn-ptr-qualifier.rs:22:17
+ |
+LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/bad-fn-ptr-qualifier.rs:22:17
+ |
+LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
+ | ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: aborting due to 16 previous errors
+
diff --git a/src/test/ui/parser/bad-if-statements.rs b/src/test/ui/parser/bad-if-statements.rs
new file mode 100644
index 000000000..2c501e3a5
--- /dev/null
+++ b/src/test/ui/parser/bad-if-statements.rs
@@ -0,0 +1,38 @@
+fn a() {
+ if {}
+ //~^ ERROR missing condition for `if` expression
+}
+
+fn b() {
+ if true && {}
+ //~^ ERROR this `if` expression is missing a block after the condition
+}
+
+fn c() {
+ let x = {};
+ if true x
+ //~^ ERROR expected `{`, found `x`
+}
+
+fn a2() {
+ if {} else {}
+ //~^ ERROR missing condition for `if` expression
+}
+
+fn b2() {
+ if true && {} else {}
+ //~^ ERROR this `if` expression is missing a block after the condition
+}
+
+fn c2() {
+ let x = {};
+ if true x else {}
+ //~^ ERROR expected `{`, found `x`
+}
+
+fn d() {
+ if true else {}
+ //~^ ERROR this `if` expression is missing a block after the condition
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-if-statements.stderr b/src/test/ui/parser/bad-if-statements.stderr
new file mode 100644
index 000000000..ee839db64
--- /dev/null
+++ b/src/test/ui/parser/bad-if-statements.stderr
@@ -0,0 +1,86 @@
+error: missing condition for `if` expression
+ --> $DIR/bad-if-statements.rs:2:7
+ |
+LL | if {}
+ | ^- if this block is the condition of the `if` expression, then it must be followed by another block
+ | |
+ | expected condition here
+
+error: this `if` expression is missing a block after the condition
+ --> $DIR/bad-if-statements.rs:7:5
+ |
+LL | if true && {}
+ | ^^
+ |
+help: this binary operation is possibly unfinished
+ --> $DIR/bad-if-statements.rs:7:8
+ |
+LL | if true && {}
+ | ^^^^^^^
+
+error: expected `{`, found `x`
+ --> $DIR/bad-if-statements.rs:13:13
+ |
+LL | if true x
+ | ^ expected `{`
+ |
+note: the `if` expression is missing a block after this condition
+ --> $DIR/bad-if-statements.rs:13:8
+ |
+LL | if true x
+ | ^^^^
+help: try placing this code inside a block
+ |
+LL | if true { x }
+ | + +
+
+error: missing condition for `if` expression
+ --> $DIR/bad-if-statements.rs:18:7
+ |
+LL | if {} else {}
+ | ^- if this block is the condition of the `if` expression, then it must be followed by another block
+ | |
+ | expected condition here
+
+error: this `if` expression is missing a block after the condition
+ --> $DIR/bad-if-statements.rs:23:5
+ |
+LL | if true && {} else {}
+ | ^^
+ |
+help: this binary operation is possibly unfinished
+ --> $DIR/bad-if-statements.rs:23:8
+ |
+LL | if true && {} else {}
+ | ^^^^^^^
+
+error: expected `{`, found `x`
+ --> $DIR/bad-if-statements.rs:29:13
+ |
+LL | if true x else {}
+ | ^ expected `{`
+ |
+note: the `if` expression is missing a block after this condition
+ --> $DIR/bad-if-statements.rs:29:8
+ |
+LL | if true x else {}
+ | ^^^^
+help: try placing this code inside a block
+ |
+LL | if true { x } else {}
+ | + +
+
+error: this `if` expression is missing a block after the condition
+ --> $DIR/bad-if-statements.rs:34:5
+ |
+LL | if true else {}
+ | ^^
+ |
+help: add a block here
+ --> $DIR/bad-if-statements.rs:34:12
+ |
+LL | if true else {}
+ | ^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/parser/bad-interpolated-block.rs b/src/test/ui/parser/bad-interpolated-block.rs
new file mode 100644
index 000000000..38d53a14b
--- /dev/null
+++ b/src/test/ui/parser/bad-interpolated-block.rs
@@ -0,0 +1,15 @@
+#![feature(label_break_value)]
+
+fn main() {}
+
+macro_rules! m {
+ ($b:block) => {
+ 'lab: $b; //~ ERROR cannot use a `block` macro fragment here
+ unsafe $b; //~ ERROR cannot use a `block` macro fragment here
+ |x: u8| -> () $b; //~ ERROR cannot use a `block` macro fragment here
+ }
+}
+
+fn foo() {
+ m!({});
+}
diff --git a/src/test/ui/parser/bad-interpolated-block.stderr b/src/test/ui/parser/bad-interpolated-block.stderr
new file mode 100644
index 000000000..77933b1bc
--- /dev/null
+++ b/src/test/ui/parser/bad-interpolated-block.stderr
@@ -0,0 +1,39 @@
+error: cannot use a `block` macro fragment here
+ --> $DIR/bad-interpolated-block.rs:7:15
+ |
+LL | 'lab: $b;
+ | ------^^
+ | |
+ | the `block` fragment is within this context
+...
+LL | m!({});
+ | ------ in this macro invocation
+ |
+ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot use a `block` macro fragment here
+ --> $DIR/bad-interpolated-block.rs:8:16
+ |
+LL | unsafe $b;
+ | -------^^
+ | |
+ | the `block` fragment is within this context
+...
+LL | m!({});
+ | ------ in this macro invocation
+ |
+ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot use a `block` macro fragment here
+ --> $DIR/bad-interpolated-block.rs:9:23
+ |
+LL | |x: u8| -> () $b;
+ | ^^ the `block` fragment is within this context
+...
+LL | m!({});
+ | ------ in this macro invocation
+ |
+ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/bad-lit-suffixes.rs b/src/test/ui/parser/bad-lit-suffixes.rs
new file mode 100644
index 000000000..446a09405
--- /dev/null
+++ b/src/test/ui/parser/bad-lit-suffixes.rs
@@ -0,0 +1,26 @@
+extern
+ "C"suffix //~ ERROR suffixes on a string literal are invalid
+ fn foo() {}
+
+extern
+ "C"suffix //~ ERROR suffixes on a string literal are invalid
+{}
+
+fn main() {
+ ""suffix; //~ ERROR suffixes on a string literal are invalid
+ b""suffix; //~ ERROR suffixes on a byte string literal are invalid
+ r#""#suffix; //~ ERROR suffixes on a string literal are invalid
+ br#""#suffix; //~ ERROR suffixes on a byte string literal are invalid
+ 'a'suffix; //~ ERROR suffixes on a char literal are invalid
+ b'a'suffix; //~ ERROR suffixes on a byte literal are invalid
+
+ 1234u1024; //~ ERROR invalid width `1024` for integer literal
+ 1234i1024; //~ ERROR invalid width `1024` for integer literal
+ 1234f1024; //~ ERROR invalid width `1024` for float literal
+ 1234.5f1024; //~ ERROR invalid width `1024` for float literal
+
+ 1234suffix; //~ ERROR invalid suffix `suffix` for number literal
+ 0b101suffix; //~ ERROR invalid suffix `suffix` for number literal
+ 1.0suffix; //~ ERROR invalid suffix `suffix` for float literal
+ 1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal
+}
diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr
new file mode 100644
index 000000000..9b5965714
--- /dev/null
+++ b/src/test/ui/parser/bad-lit-suffixes.stderr
@@ -0,0 +1,114 @@
+error: suffixes on a string literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:2:5
+ |
+LL | "C"suffix
+ | ^^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a string literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:6:5
+ |
+LL | "C"suffix
+ | ^^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a string literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:10:5
+ |
+LL | ""suffix;
+ | ^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a byte string literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:11:5
+ |
+LL | b""suffix;
+ | ^^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a string literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:12:5
+ |
+LL | r#""#suffix;
+ | ^^^^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a byte string literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:13:5
+ |
+LL | br#""#suffix;
+ | ^^^^^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a char literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:14:5
+ |
+LL | 'a'suffix;
+ | ^^^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a byte literal are invalid
+ --> $DIR/bad-lit-suffixes.rs:15:5
+ |
+LL | b'a'suffix;
+ | ^^^^^^^^^^ invalid suffix `suffix`
+
+error: invalid width `1024` for integer literal
+ --> $DIR/bad-lit-suffixes.rs:17:5
+ |
+LL | 1234u1024;
+ | ^^^^^^^^^
+ |
+ = help: valid widths are 8, 16, 32, 64 and 128
+
+error: invalid width `1024` for integer literal
+ --> $DIR/bad-lit-suffixes.rs:18:5
+ |
+LL | 1234i1024;
+ | ^^^^^^^^^
+ |
+ = help: valid widths are 8, 16, 32, 64 and 128
+
+error: invalid width `1024` for float literal
+ --> $DIR/bad-lit-suffixes.rs:19:5
+ |
+LL | 1234f1024;
+ | ^^^^^^^^^
+ |
+ = help: valid widths are 32 and 64
+
+error: invalid width `1024` for float literal
+ --> $DIR/bad-lit-suffixes.rs:20:5
+ |
+LL | 1234.5f1024;
+ | ^^^^^^^^^^^
+ |
+ = help: valid widths are 32 and 64
+
+error: invalid suffix `suffix` for number literal
+ --> $DIR/bad-lit-suffixes.rs:22:5
+ |
+LL | 1234suffix;
+ | ^^^^^^^^^^ invalid suffix `suffix`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `suffix` for number literal
+ --> $DIR/bad-lit-suffixes.rs:23:5
+ |
+LL | 0b101suffix;
+ | ^^^^^^^^^^^ invalid suffix `suffix`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `suffix` for float literal
+ --> $DIR/bad-lit-suffixes.rs:24:5
+ |
+LL | 1.0suffix;
+ | ^^^^^^^^^ invalid suffix `suffix`
+ |
+ = help: valid suffixes are `f32` and `f64`
+
+error: invalid suffix `suffix` for float literal
+ --> $DIR/bad-lit-suffixes.rs:25:5
+ |
+LL | 1.0e10suffix;
+ | ^^^^^^^^^^^^ invalid suffix `suffix`
+ |
+ = help: valid suffixes are `f32` and `f64`
+
+error: aborting due to 16 previous errors
+
diff --git a/src/test/ui/parser/bad-match.rs b/src/test/ui/parser/bad-match.rs
new file mode 100644
index 000000000..04100d170
--- /dev/null
+++ b/src/test/ui/parser/bad-match.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let isize x = 5; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `x`
+ match x;
+}
diff --git a/src/test/ui/parser/bad-match.stderr b/src/test/ui/parser/bad-match.stderr
new file mode 100644
index 000000000..13784c409
--- /dev/null
+++ b/src/test/ui/parser/bad-match.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `x`
+ --> $DIR/bad-match.rs:2:13
+ |
+LL | let isize x = 5;
+ | ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-name.rs b/src/test/ui/parser/bad-name.rs
new file mode 100644
index 000000000..9b4271692
--- /dev/null
+++ b/src/test/ui/parser/bad-name.rs
@@ -0,0 +1,5 @@
+// error-pattern: expected
+
+fn main() {
+ let x.y::<isize>.z foo;
+}
diff --git a/src/test/ui/parser/bad-name.stderr b/src/test/ui/parser/bad-name.stderr
new file mode 100644
index 000000000..a36b67794
--- /dev/null
+++ b/src/test/ui/parser/bad-name.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+ --> $DIR/bad-name.rs:4:8
+ |
+LL | let x.y::<isize>.z foo;
+ | ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-pointer-type.rs b/src/test/ui/parser/bad-pointer-type.rs
new file mode 100644
index 000000000..59e5e0c5d
--- /dev/null
+++ b/src/test/ui/parser/bad-pointer-type.rs
@@ -0,0 +1,5 @@
+fn foo(_: *()) {
+ //~^ ERROR expected mut or const in raw pointer type
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-pointer-type.stderr b/src/test/ui/parser/bad-pointer-type.stderr
new file mode 100644
index 000000000..e18c220af
--- /dev/null
+++ b/src/test/ui/parser/bad-pointer-type.stderr
@@ -0,0 +1,10 @@
+error: expected mut or const in raw pointer type
+ --> $DIR/bad-pointer-type.rs:1:11
+ |
+LL | fn foo(_: *()) {
+ | ^ expected mut or const in raw pointer type
+ |
+ = help: use `*mut T` or `*const T` as appropriate
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-struct-following-where.rs b/src/test/ui/parser/bad-struct-following-where.rs
new file mode 100644
index 000000000..823880b1b
--- /dev/null
+++ b/src/test/ui/parser/bad-struct-following-where.rs
@@ -0,0 +1,2 @@
+struct A where T: Sized !
+//~^ ERROR expected `{` after struct name, found
diff --git a/src/test/ui/parser/bad-struct-following-where.stderr b/src/test/ui/parser/bad-struct-following-where.stderr
new file mode 100644
index 000000000..bb79776dc
--- /dev/null
+++ b/src/test/ui/parser/bad-struct-following-where.stderr
@@ -0,0 +1,8 @@
+error: expected `{` after struct name, found `!`
+ --> $DIR/bad-struct-following-where.rs:1:25
+ |
+LL | struct A where T: Sized !
+ | ^ expected `{` after struct name
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-value-ident-false.rs b/src/test/ui/parser/bad-value-ident-false.rs
new file mode 100644
index 000000000..4645ab4a7
--- /dev/null
+++ b/src/test/ui/parser/bad-value-ident-false.rs
@@ -0,0 +1,2 @@
+fn false() { } //~ ERROR expected identifier, found keyword `false`
+fn main() { }
diff --git a/src/test/ui/parser/bad-value-ident-false.stderr b/src/test/ui/parser/bad-value-ident-false.stderr
new file mode 100644
index 000000000..30c05ecf3
--- /dev/null
+++ b/src/test/ui/parser/bad-value-ident-false.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `false`
+ --> $DIR/bad-value-ident-false.rs:1:4
+ |
+LL | fn false() { }
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `false` to use it as an identifier
+ |
+LL | fn r#false() { }
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bad-value-ident-true.rs b/src/test/ui/parser/bad-value-ident-true.rs
new file mode 100644
index 000000000..0f64266d3
--- /dev/null
+++ b/src/test/ui/parser/bad-value-ident-true.rs
@@ -0,0 +1,2 @@
+fn true() { } //~ ERROR expected identifier, found keyword `true`
+fn main() { }
diff --git a/src/test/ui/parser/bad-value-ident-true.stderr b/src/test/ui/parser/bad-value-ident-true.stderr
new file mode 100644
index 000000000..74137fa70
--- /dev/null
+++ b/src/test/ui/parser/bad-value-ident-true.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `true`
+ --> $DIR/bad-value-ident-true.rs:1:4
+ |
+LL | fn true() { }
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `true` to use it as an identifier
+ |
+LL | fn r#true() { }
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bare-struct-body.rs b/src/test/ui/parser/bare-struct-body.rs
new file mode 100644
index 000000000..a557e861d
--- /dev/null
+++ b/src/test/ui/parser/bare-struct-body.rs
@@ -0,0 +1,15 @@
+struct Foo {
+ val: (),
+}
+
+fn foo() -> Foo { //~ ERROR struct literal body without path
+ val: (),
+}
+
+fn main() {
+ let x = foo();
+ x.val == 42; //~ ERROR mismatched types
+ let x = { //~ ERROR struct literal body without path
+ val: (),
+ };
+}
diff --git a/src/test/ui/parser/bare-struct-body.stderr b/src/test/ui/parser/bare-struct-body.stderr
new file mode 100644
index 000000000..c77992b2c
--- /dev/null
+++ b/src/test/ui/parser/bare-struct-body.stderr
@@ -0,0 +1,41 @@
+error: struct literal body without path
+ --> $DIR/bare-struct-body.rs:5:17
+ |
+LL | fn foo() -> Foo {
+ | _________________^
+LL | | val: (),
+LL | | }
+ | |_^
+ |
+help: you might have forgotten to add the struct literal inside the block
+ |
+LL ~ fn foo() -> Foo { SomeStruct {
+LL | val: (),
+LL ~ } }
+ |
+
+error: struct literal body without path
+ --> $DIR/bare-struct-body.rs:12:13
+ |
+LL | let x = {
+ | _____________^
+LL | | val: (),
+LL | | };
+ | |_____^
+ |
+help: you might have forgotten to add the struct literal inside the block
+ |
+LL ~ let x = { SomeStruct {
+LL | val: (),
+LL ~ } };
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/bare-struct-body.rs:11:14
+ |
+LL | x.val == 42;
+ | ^^ expected `()`, found integer
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/bastion-of-the-turbofish.rs b/src/test/ui/parser/bastion-of-the-turbofish.rs
new file mode 100644
index 000000000..e12857008
--- /dev/null
+++ b/src/test/ui/parser/bastion-of-the-turbofish.rs
@@ -0,0 +1,43 @@
+// check-pass
+
+// Bastion of the Turbofish
+// ------------------------
+// Beware travellers, lest you venture into waters callous and unforgiving,
+// where hope must be abandoned, ere it is cruelly torn from you. For here
+// stands the bastion of the Turbofish: an impenetrable fortress holding
+// unshaking against those who would dare suggest the supererogation of the
+// Turbofish.
+//
+// Once I was young and foolish and had the impudence to imagine that I could
+// shake free from the coils by which that creature had us tightly bound. I
+// dared to suggest that there was a better way: a brighter future, in which
+// Rustaceans both new and old could be rid of that vile beast. But alas! In
+// my foolhardiness my ignorance was unveiled and my dreams were dashed
+// unforgivingly against the rock of syntactic ambiguity.
+//
+// This humble program, small and insignificant though it might seem,
+// demonstrates that to which we had previously cast a blind eye: an ambiguity
+// in permitting generic arguments to be provided without the consent of the
+// Great Turbofish. Should you be so naïve as to try to revolt against its
+// mighty clutches, here shall its wrath be indomitably displayed. This
+// program must pass for all eternity: forever watched by the guardian angel
+// which gave this beast its name, and stands fundamentally at odds with the
+// impetuous rebellion against the Turbofish.
+//
+// My heart aches in sorrow, for I know I am defeated. Let this be a warning
+// to all those who come after: for they too must overcome the impassible
+// hurdle of defeating the great beast, championed by a resolute winged
+// guardian.
+//
+// Here stands the Bastion of the Turbofish, a memorial to Anna Harren,
+// Guardian Angel of these Hallowed Grounds. <3
+
+// See https://github.com/rust-lang/rust/pull/53562
+// and https://github.com/rust-lang/rfcs/pull/2527
+// and https://twitter.com/garblefart/status/1393236602856611843
+// for context.
+
+fn main() {
+ let (the, guardian, stands, resolute) = ("the", "Turbofish", "remains", "undefeated");
+ let _: (bool, bool) = (the<guardian, stands>(resolute));
+}
diff --git a/src/test/ui/parser/better-expected.rs b/src/test/ui/parser/better-expected.rs
new file mode 100644
index 000000000..16b61caa4
--- /dev/null
+++ b/src/test/ui/parser/better-expected.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
+}
diff --git a/src/test/ui/parser/better-expected.stderr b/src/test/ui/parser/better-expected.stderr
new file mode 100644
index 000000000..21bf8d19a
--- /dev/null
+++ b/src/test/ui/parser/better-expected.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
+ --> $DIR/better-expected.rs:2:19
+ |
+LL | let x: [isize 3];
+ | - ^ expected one of 7 possible tokens
+ | |
+ | while parsing the type for `x`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bind-struct-early-modifiers.rs b/src/test/ui/parser/bind-struct-early-modifiers.rs
new file mode 100644
index 000000000..c4b1937de
--- /dev/null
+++ b/src/test/ui/parser/bind-struct-early-modifiers.rs
@@ -0,0 +1,7 @@
+fn main() {
+ struct Foo { x: isize }
+ match (Foo { x: 10 }) {
+ Foo { ref x: ref x } => {}, //~ ERROR expected `,`
+ _ => {}
+ }
+}
diff --git a/src/test/ui/parser/bind-struct-early-modifiers.stderr b/src/test/ui/parser/bind-struct-early-modifiers.stderr
new file mode 100644
index 000000000..b35762a88
--- /dev/null
+++ b/src/test/ui/parser/bind-struct-early-modifiers.stderr
@@ -0,0 +1,10 @@
+error: expected `,`
+ --> $DIR/bind-struct-early-modifiers.rs:4:20
+ |
+LL | Foo { ref x: ref x } => {},
+ | --- ^
+ | |
+ | while parsing the fields for this pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/block-no-opening-brace.rs b/src/test/ui/parser/block-no-opening-brace.rs
new file mode 100644
index 000000000..8a6599488
--- /dev/null
+++ b/src/test/ui/parser/block-no-opening-brace.rs
@@ -0,0 +1,31 @@
+// edition:2018
+
+#![feature(try_blocks)]
+
+fn main() {}
+
+fn f1() {
+ loop
+ let x = 0; //~ ERROR expected `{`, found keyword `let`
+ drop(0);
+ }
+
+fn f2() {
+ while true
+ let x = 0; //~ ERROR expected `{`, found keyword `let`
+ }
+
+fn f3() {
+ for x in 0..1
+ let x = 0; //~ ERROR expected `{`, found keyword `let`
+ }
+
+fn f4() {
+ try //~ ERROR expected expression, found reserved keyword `try`
+ let x = 0;
+ }
+
+fn f5() {
+ async
+ let x = 0; //~ ERROR expected one of `move`, `|`, or `||`, found keyword `let`
+ }
diff --git a/src/test/ui/parser/block-no-opening-brace.stderr b/src/test/ui/parser/block-no-opening-brace.stderr
new file mode 100644
index 000000000..f232f480c
--- /dev/null
+++ b/src/test/ui/parser/block-no-opening-brace.stderr
@@ -0,0 +1,55 @@
+error: expected `{`, found keyword `let`
+ --> $DIR/block-no-opening-brace.rs:9:9
+ |
+LL | loop
+ | ---- while parsing this `loop` expression
+LL | let x = 0;
+ | ^^^ expected `{`
+ |
+help: try placing this code inside a block
+ |
+LL | { let x = 0; }
+ | + +
+
+error: expected `{`, found keyword `let`
+ --> $DIR/block-no-opening-brace.rs:15:9
+ |
+LL | while true
+ | ----- ---- this `while` condition successfully parsed
+ | |
+ | while parsing the body of this `while` expression
+LL | let x = 0;
+ | ^^^ expected `{`
+ |
+help: try placing this code inside a block
+ |
+LL | { let x = 0; }
+ | + +
+
+error: expected `{`, found keyword `let`
+ --> $DIR/block-no-opening-brace.rs:20:9
+ |
+LL | let x = 0;
+ | ^^^ expected `{`
+ |
+help: try placing this code inside a block
+ |
+LL | { let x = 0; }
+ | + +
+
+error: expected expression, found reserved keyword `try`
+ --> $DIR/block-no-opening-brace.rs:24:5
+ |
+LL | try
+ | ^^^ expected expression
+
+error: expected one of `move`, `|`, or `||`, found keyword `let`
+ --> $DIR/block-no-opening-brace.rs:30:9
+ |
+LL | async
+ | - expected one of `move`, `|`, or `||`
+LL | let x = 0;
+ | ^^^ unexpected token
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/parser/bound-single-question-mark.rs b/src/test/ui/parser/bound-single-question-mark.rs
new file mode 100644
index 000000000..64d702d14
--- /dev/null
+++ b/src/test/ui/parser/bound-single-question-mark.rs
@@ -0,0 +1 @@
+fn f<T: ?>() {} //~ ERROR expected identifier, found `>`
diff --git a/src/test/ui/parser/bound-single-question-mark.stderr b/src/test/ui/parser/bound-single-question-mark.stderr
new file mode 100644
index 000000000..82937a517
--- /dev/null
+++ b/src/test/ui/parser/bound-single-question-mark.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `>`
+ --> $DIR/bound-single-question-mark.rs:1:10
+ |
+LL | fn f<T: ?>() {}
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-lifetime-1.rs b/src/test/ui/parser/bounds-lifetime-1.rs
new file mode 100644
index 000000000..e458f644c
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-1.rs
@@ -0,0 +1,3 @@
+type A = for<'a 'b> fn(); //~ ERROR expected one of `,`, `:`, or `>`, found `'b`
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-lifetime-1.stderr b/src/test/ui/parser/bounds-lifetime-1.stderr
new file mode 100644
index 000000000..000e84f63
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-1.stderr
@@ -0,0 +1,8 @@
+error: expected one of `,`, `:`, or `>`, found `'b`
+ --> $DIR/bounds-lifetime-1.rs:1:17
+ |
+LL | type A = for<'a 'b> fn();
+ | ^^ expected one of `,`, `:`, or `>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-lifetime-2.rs b/src/test/ui/parser/bounds-lifetime-2.rs
new file mode 100644
index 000000000..f184107bb
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-2.rs
@@ -0,0 +1,3 @@
+type A = for<'a + 'b> fn(); //~ ERROR expected one of `,`, `:`, or `>`, found `+`
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-lifetime-2.stderr b/src/test/ui/parser/bounds-lifetime-2.stderr
new file mode 100644
index 000000000..dd3e69c11
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-2.stderr
@@ -0,0 +1,8 @@
+error: expected one of `,`, `:`, or `>`, found `+`
+ --> $DIR/bounds-lifetime-2.rs:1:17
+ |
+LL | type A = for<'a + 'b> fn();
+ | ^ expected one of `,`, `:`, or `>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-lifetime-where-1.rs b/src/test/ui/parser/bounds-lifetime-where-1.rs
new file mode 100644
index 000000000..f1a002a9f
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-where-1.rs
@@ -0,0 +1,3 @@
+type A where 'a; //~ ERROR expected `:`, found `;`
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-lifetime-where-1.stderr b/src/test/ui/parser/bounds-lifetime-where-1.stderr
new file mode 100644
index 000000000..b6bd86693
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-where-1.stderr
@@ -0,0 +1,8 @@
+error: expected `:`, found `;`
+ --> $DIR/bounds-lifetime-where-1.rs:1:16
+ |
+LL | type A where 'a;
+ | ^ expected `:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-lifetime-where.rs b/src/test/ui/parser/bounds-lifetime-where.rs
new file mode 100644
index 000000000..7ff75233d
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-where.rs
@@ -0,0 +1,10 @@
+type A where 'a: 'b + 'c = u8; // OK
+type A where 'a: 'b, = u8; // OK
+type A where 'a: = u8; // OK
+type A where 'a:, = u8; // OK
+type A where 'a: 'b + 'c = u8; // OK
+type A where = u8; // OK
+type A where 'a: 'b + = u8; // OK
+type A where , = u8; //~ ERROR expected one of `;`, `=`, `where`, lifetime, or type, found `,`
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-lifetime-where.stderr b/src/test/ui/parser/bounds-lifetime-where.stderr
new file mode 100644
index 000000000..785a1fb67
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime-where.stderr
@@ -0,0 +1,8 @@
+error: expected one of `;`, `=`, `where`, lifetime, or type, found `,`
+ --> $DIR/bounds-lifetime-where.rs:8:14
+ |
+LL | type A where , = u8;
+ | ^ expected one of `;`, `=`, `where`, lifetime, or type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-lifetime.rs b/src/test/ui/parser/bounds-lifetime.rs
new file mode 100644
index 000000000..c9251ac53
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime.rs
@@ -0,0 +1,11 @@
+type A = for<'a:> fn(); // OK
+type A = for<'a:,> fn(); // OK
+type A = for<'a> fn(); // OK
+type A = for<> fn(); // OK
+type A = for<'a: 'b + 'c> fn(); // OK (rejected later by ast_validation)
+type A = for<'a: 'b,> fn(); // OK(rejected later by ast_validation)
+type A = for<'a: 'b +> fn(); // OK (rejected later by ast_validation)
+type A = for<'a, T> fn(); // OK (rejected later by ast_validation)
+type A = for<,> fn(); //~ ERROR expected one of `#`, `>`, `const`, identifier, or lifetime
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-lifetime.stderr b/src/test/ui/parser/bounds-lifetime.stderr
new file mode 100644
index 000000000..e47a21d89
--- /dev/null
+++ b/src/test/ui/parser/bounds-lifetime.stderr
@@ -0,0 +1,8 @@
+error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/bounds-lifetime.rs:9:14
+ |
+LL | type A = for<,> fn();
+ | ^ expected one of `#`, `>`, `const`, identifier, or lifetime
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-obj-parens.rs b/src/test/ui/parser/bounds-obj-parens.rs
new file mode 100644
index 000000000..8c446d27d
--- /dev/null
+++ b/src/test/ui/parser/bounds-obj-parens.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+#![allow(bare_trait_objects)]
+
+type A = Box<(Fn(u8) -> u8) + 'static + Send + Sync>; // OK (but see #39318)
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-type-where.rs b/src/test/ui/parser/bounds-type-where.rs
new file mode 100644
index 000000000..2520ecb29
--- /dev/null
+++ b/src/test/ui/parser/bounds-type-where.rs
@@ -0,0 +1,11 @@
+type A where for<'a> for<'b> Trait1 + ?Trait2: 'a + Trait = u8; // OK
+type A where T: Trait, = u8; // OK
+type A where T: = u8; // OK
+type A where T:, = u8; // OK
+type A where T: Trait + Trait = u8; // OK
+type A where = u8; // OK
+type A where T: Trait + = u8; // OK
+type A where T, = u8;
+//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,`
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-type-where.stderr b/src/test/ui/parser/bounds-type-where.stderr
new file mode 100644
index 000000000..5636ee75c
--- /dev/null
+++ b/src/test/ui/parser/bounds-type-where.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,`
+ --> $DIR/bounds-type-where.rs:8:15
+ |
+LL | type A where T, = u8;
+ | ^ expected one of 8 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/bounds-type.rs b/src/test/ui/parser/bounds-type.rs
new file mode 100644
index 000000000..4ae4549ea
--- /dev/null
+++ b/src/test/ui/parser/bounds-type.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z parse-only
+
+struct S<
+ T: 'a + Tr, // OK
+ T: Tr + 'a, // OK
+ T: 'a, // OK
+ T:, // OK
+ T: ?for<'a> Trait, // OK
+ T: Tr +, // OK
+ T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
+
+ T: ~const Tr, // OK
+ T: ~const ?Tr, // OK
+ T: ~const Tr + 'a, // OK
+ T: ~const 'a, //~ ERROR `~const` may only modify trait bounds, not lifetime bounds
+>;
+
+fn main() {}
diff --git a/src/test/ui/parser/bounds-type.stderr b/src/test/ui/parser/bounds-type.stderr
new file mode 100644
index 000000000..005bc1e54
--- /dev/null
+++ b/src/test/ui/parser/bounds-type.stderr
@@ -0,0 +1,14 @@
+error: `?` may only modify trait bounds, not lifetime bounds
+ --> $DIR/bounds-type.rs:10:8
+ |
+LL | T: ?'a,
+ | ^
+
+error: `~const` may only modify trait bounds, not lifetime bounds
+ --> $DIR/bounds-type.rs:15:8
+ |
+LL | T: ~const 'a,
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs
new file mode 100644
index 000000000..05a510b24
--- /dev/null
+++ b/src/test/ui/parser/byte-literals.rs
@@ -0,0 +1,12 @@
+// ignore-tidy-tab
+
+static FOO: u8 = b'\f'; //~ ERROR unknown byte escape
+
+pub fn main() {
+ b'\f'; //~ ERROR unknown byte escape
+ b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z`
+ b' '; //~ ERROR byte constant must be escaped
+ b'''; //~ ERROR byte constant must be escaped
+ b'é'; //~ ERROR non-ASCII character in byte constant
+ b'a //~ ERROR unterminated byte constant [E0763]
+}
diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr
new file mode 100644
index 000000000..c3d000616
--- /dev/null
+++ b/src/test/ui/parser/byte-literals.stderr
@@ -0,0 +1,54 @@
+error: unknown byte escape: `f`
+ --> $DIR/byte-literals.rs:3:21
+ |
+LL | static FOO: u8 = b'\f';
+ | ^ unknown byte escape
+ |
+ = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals>
+
+error: unknown byte escape: `f`
+ --> $DIR/byte-literals.rs:6:8
+ |
+LL | b'\f';
+ | ^ unknown byte escape
+ |
+ = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals>
+
+error: invalid character in numeric character escape: `Z`
+ --> $DIR/byte-literals.rs:7:10
+ |
+LL | b'\x0Z';
+ | ^ invalid character in numeric character escape
+
+error: byte constant must be escaped: `\t`
+ --> $DIR/byte-literals.rs:8:7
+ |
+LL | b' ';
+ | ^^^^ help: escape the character: `\t`
+
+error: byte constant must be escaped: `'`
+ --> $DIR/byte-literals.rs:9:7
+ |
+LL | b''';
+ | ^ help: escape the character: `\'`
+
+error: non-ASCII character in byte constant
+ --> $DIR/byte-literals.rs:10:7
+ |
+LL | b'é';
+ | ^ byte constant must be ASCII
+ |
+help: if you meant to use the unicode code point for 'é', use a \xHH escape
+ |
+LL | b'\xE9';
+ | ~~~~
+
+error[E0763]: unterminated byte constant
+ --> $DIR/byte-literals.rs:11:6
+ |
+LL | b'a
+ | ^^^^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0763`.
diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs
new file mode 100644
index 000000000..b1f11024a
--- /dev/null
+++ b/src/test/ui/parser/byte-string-literals.rs
@@ -0,0 +1,9 @@
+static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape
+
+pub fn main() {
+ b"\f"; //~ ERROR unknown byte escape
+ b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z`
+ b"é"; //~ ERROR non-ASCII character in byte constant
+ br##"é"##; //~ ERROR raw byte string must be ASCII
+ b"a //~ ERROR unterminated double quote byte string
+}
diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr
new file mode 100644
index 000000000..3b8b3692e
--- /dev/null
+++ b/src/test/ui/parser/byte-string-literals.stderr
@@ -0,0 +1,50 @@
+error: unknown byte escape: `f`
+ --> $DIR/byte-string-literals.rs:1:32
+ |
+LL | static FOO: &'static [u8] = b"\f";
+ | ^ unknown byte escape
+ |
+ = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals>
+
+error: unknown byte escape: `f`
+ --> $DIR/byte-string-literals.rs:4:8
+ |
+LL | b"\f";
+ | ^ unknown byte escape
+ |
+ = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals>
+
+error: invalid character in numeric character escape: `Z`
+ --> $DIR/byte-string-literals.rs:5:10
+ |
+LL | b"\x0Z";
+ | ^ invalid character in numeric character escape
+
+error: non-ASCII character in byte constant
+ --> $DIR/byte-string-literals.rs:6:7
+ |
+LL | b"é";
+ | ^ byte constant must be ASCII
+ |
+help: if you meant to use the unicode code point for 'é', use a \xHH escape
+ |
+LL | b"\xE9";
+ | ~~~~
+
+error: raw byte string must be ASCII
+ --> $DIR/byte-string-literals.rs:7:10
+ |
+LL | br##"é"##;
+ | ^ must be ASCII
+
+error[E0766]: unterminated double quote byte string
+ --> $DIR/byte-string-literals.rs:8:6
+ |
+LL | b"a
+ | ______^
+LL | | }
+ | |__^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0766`.
diff --git a/src/test/ui/parser/can-begin-expr-check.rs b/src/test/ui/parser/can-begin-expr-check.rs
new file mode 100644
index 000000000..e5be8de79
--- /dev/null
+++ b/src/test/ui/parser/can-begin-expr-check.rs
@@ -0,0 +1,20 @@
+pub fn main() {
+
+ return;
+ return ();
+ return as ();
+ return return as ();
+ return return return;
+
+ return if true {
+ ()
+ } else {
+ ()
+ };
+
+ loop {
+ return break as ();
+ }
+
+ return enum; //~ ERROR expected one of `;`, `}`, or an operator, found keyword `enum`
+}
diff --git a/src/test/ui/parser/can-begin-expr-check.stderr b/src/test/ui/parser/can-begin-expr-check.stderr
new file mode 100644
index 000000000..9569ababa
--- /dev/null
+++ b/src/test/ui/parser/can-begin-expr-check.stderr
@@ -0,0 +1,8 @@
+error: expected one of `;`, `}`, or an operator, found keyword `enum`
+ --> $DIR/can-begin-expr-check.rs:19:12
+ |
+LL | return enum;
+ | ^^^^ expected one of `;`, `}`, or an operator
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/chained-comparison-suggestion.rs b/src/test/ui/parser/chained-comparison-suggestion.rs
new file mode 100644
index 000000000..bbd46082c
--- /dev/null
+++ b/src/test/ui/parser/chained-comparison-suggestion.rs
@@ -0,0 +1,53 @@
+// Check that we get nice suggestions when attempting a chained comparison.
+
+fn comp1() {
+ 1 < 2 <= 3; //~ ERROR comparison operators cannot be chained
+ //~^ ERROR mismatched types
+}
+
+fn comp2() {
+ 1 < 2 < 3; //~ ERROR comparison operators cannot be chained
+}
+
+fn comp3() {
+ 1 <= 2 < 3; //~ ERROR comparison operators cannot be chained
+ //~^ ERROR mismatched types
+}
+
+fn comp4() {
+ 1 <= 2 <= 3; //~ ERROR comparison operators cannot be chained
+ //~^ ERROR mismatched types
+}
+
+fn comp5() {
+ 1 > 2 >= 3; //~ ERROR comparison operators cannot be chained
+ //~^ ERROR mismatched types
+}
+
+fn comp6() {
+ 1 > 2 > 3; //~ ERROR comparison operators cannot be chained
+}
+
+fn comp7() {
+ 1 >= 2 > 3; //~ ERROR comparison operators cannot be chained
+}
+
+fn comp8() {
+ 1 >= 2 >= 3; //~ ERROR comparison operators cannot be chained
+ //~^ ERROR mismatched types
+}
+
+fn comp9() {
+ 1 == 2 < 3; //~ ERROR comparison operators cannot be chained
+}
+
+fn comp10() {
+ 1 > 2 == false; //~ ERROR comparison operators cannot be chained
+}
+
+fn comp11() {
+ 1 == 2 == 3; //~ ERROR comparison operators cannot be chained
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/chained-comparison-suggestion.stderr b/src/test/ui/parser/chained-comparison-suggestion.stderr
new file mode 100644
index 000000000..694b0b6eb
--- /dev/null
+++ b/src/test/ui/parser/chained-comparison-suggestion.stderr
@@ -0,0 +1,160 @@
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:4:7
+ |
+LL | 1 < 2 <= 3;
+ | ^ ^^
+ |
+help: split the comparison into two
+ |
+LL | 1 < 2 && 2 <= 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:9:7
+ |
+LL | 1 < 2 < 3;
+ | ^ ^
+ |
+help: split the comparison into two
+ |
+LL | 1 < 2 && 2 < 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:13:7
+ |
+LL | 1 <= 2 < 3;
+ | ^^ ^
+ |
+help: split the comparison into two
+ |
+LL | 1 <= 2 && 2 < 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:18:7
+ |
+LL | 1 <= 2 <= 3;
+ | ^^ ^^
+ |
+help: split the comparison into two
+ |
+LL | 1 <= 2 && 2 <= 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:23:7
+ |
+LL | 1 > 2 >= 3;
+ | ^ ^^
+ |
+help: split the comparison into two
+ |
+LL | 1 > 2 && 2 >= 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:28:7
+ |
+LL | 1 > 2 > 3;
+ | ^ ^
+ |
+help: split the comparison into two
+ |
+LL | 1 > 2 && 2 > 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:32:7
+ |
+LL | 1 >= 2 > 3;
+ | ^^ ^
+ |
+help: split the comparison into two
+ |
+LL | 1 >= 2 && 2 > 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:36:7
+ |
+LL | 1 >= 2 >= 3;
+ | ^^ ^^
+ |
+help: split the comparison into two
+ |
+LL | 1 >= 2 && 2 >= 3;
+ | ++++
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:41:7
+ |
+LL | 1 == 2 < 3;
+ | ^^ ^
+ |
+help: parenthesize the comparison
+ |
+LL | 1 == (2 < 3);
+ | + +
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:45:7
+ |
+LL | 1 > 2 == false;
+ | ^ ^^
+ |
+help: parenthesize the comparison
+ |
+LL | (1 > 2) == false;
+ | + +
+
+error: comparison operators cannot be chained
+ --> $DIR/chained-comparison-suggestion.rs:49:7
+ |
+LL | 1 == 2 == 3;
+ | ^^ ^^
+ |
+help: split the comparison into two
+ |
+LL | 1 == 2 && 2 == 3;
+ | ++++
+
+error[E0308]: mismatched types
+ --> $DIR/chained-comparison-suggestion.rs:4:14
+ |
+LL | 1 < 2 <= 3;
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/chained-comparison-suggestion.rs:13:14
+ |
+LL | 1 <= 2 < 3;
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/chained-comparison-suggestion.rs:18:15
+ |
+LL | 1 <= 2 <= 3;
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/chained-comparison-suggestion.rs:23:14
+ |
+LL | 1 > 2 >= 3;
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/chained-comparison-suggestion.rs:36:15
+ |
+LL | 1 >= 2 >= 3;
+ | ^ expected `bool`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/chained-comparison-suggestion.rs:49:15
+ |
+LL | 1 == 2 == 3;
+ | ^ expected `bool`, found integer
+
+error: aborting due to 17 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/char/whitespace-character-literal.rs b/src/test/ui/parser/char/whitespace-character-literal.rs
new file mode 100644
index 000000000..de5e09204
--- /dev/null
+++ b/src/test/ui/parser/char/whitespace-character-literal.rs
@@ -0,0 +1,10 @@
+// This tests that the error generated when a character literal has multiple
+// characters in it contains a note about non-printing characters.
+
+fn main() {
+ let _hair_space_around = ' x​';
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}`
+ //~| HELP: consider removing the non-printing characters
+ //~| SUGGESTION: x
+}
diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr
new file mode 100644
index 000000000..d73de41a8
--- /dev/null
+++ b/src/test/ui/parser/char/whitespace-character-literal.stderr
@@ -0,0 +1,16 @@
+error: character literal may only contain one codepoint
+ --> $DIR/whitespace-character-literal.rs:5:30
+ |
+LL | let _hair_space_around = ' x​';
+ | ^--^
+ | |
+ | help: consider removing the non-printing characters: `x`
+ |
+note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}`
+ --> $DIR/whitespace-character-literal.rs:5:31
+ |
+LL | let _hair_space_around = ' x​';
+ | ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/circular_modules_hello.rs b/src/test/ui/parser/circular_modules_hello.rs
new file mode 100644
index 000000000..6968ca97b
--- /dev/null
+++ b/src/test/ui/parser/circular_modules_hello.rs
@@ -0,0 +1,8 @@
+// ignore-test: this is an auxiliary file for circular-modules-main.rs
+
+#[path = "circular_modules_main.rs"]
+mod circular_modules_main;
+
+pub fn say_hello() {
+ println!("{}", circular_modules_main::hi_str());
+}
diff --git a/src/test/ui/parser/circular_modules_main.rs b/src/test/ui/parser/circular_modules_main.rs
new file mode 100644
index 000000000..d4b47efe6
--- /dev/null
+++ b/src/test/ui/parser/circular_modules_main.rs
@@ -0,0 +1,12 @@
+// error-pattern: circular modules
+
+#[path = "circular_modules_hello.rs"]
+mod circular_modules_hello;
+
+pub fn hi_str() -> String {
+ "Hi!".to_string()
+}
+
+fn main() {
+ circular_modules_hello::say_hello();
+}
diff --git a/src/test/ui/parser/circular_modules_main.stderr b/src/test/ui/parser/circular_modules_main.stderr
new file mode 100644
index 000000000..1094def60
--- /dev/null
+++ b/src/test/ui/parser/circular_modules_main.stderr
@@ -0,0 +1,25 @@
+error: circular modules: $DIR/circular_modules_main.rs -> $DIR/circular_modules_hello.rs -> $DIR/circular_modules_main.rs
+ --> $DIR/circular_modules_hello.rs:4:1
+ |
+LL | mod circular_modules_main;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0425]: cannot find function `hi_str` in module `circular_modules_main`
+ --> $DIR/circular_modules_hello.rs:7:43
+ |
+LL | println!("{}", circular_modules_main::hi_str());
+ | ^^^^^^ not found in `circular_modules_main`
+ |
+help: consider importing this function
+ |
+LL | use hi_str;
+ |
+help: if you import `hi_str`, refer to it directly
+ |
+LL - println!("{}", circular_modules_main::hi_str());
+LL + println!("{}", hi_str());
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/class-implements-bad-trait.rs b/src/test/ui/parser/class-implements-bad-trait.rs
new file mode 100644
index 000000000..f2f85d026
--- /dev/null
+++ b/src/test/ui/parser/class-implements-bad-trait.rs
@@ -0,0 +1,9 @@
+// error-pattern:nonexistent
+class cat : nonexistent {
+ let meows: usize;
+ new(in_x : usize) { self.meows = in_x; }
+}
+
+fn main() {
+ let nyan = cat(0);
+}
diff --git a/src/test/ui/parser/class-implements-bad-trait.stderr b/src/test/ui/parser/class-implements-bad-trait.stderr
new file mode 100644
index 000000000..3a4dea95d
--- /dev/null
+++ b/src/test/ui/parser/class-implements-bad-trait.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found `cat`
+ --> $DIR/class-implements-bad-trait.rs:2:7
+ |
+LL | class cat : nonexistent {
+ | ^^^ expected one of `!` or `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/closure-return-syntax.rs b/src/test/ui/parser/closure-return-syntax.rs
new file mode 100644
index 000000000..c6a08abef
--- /dev/null
+++ b/src/test/ui/parser/closure-return-syntax.rs
@@ -0,0 +1,7 @@
+// Test that we cannot parse a closure with an explicit return type
+// unless it uses braces.
+
+fn main() {
+ let x = || -> i32 22;
+ //~^ ERROR expected `{`, found `22`
+}
diff --git a/src/test/ui/parser/closure-return-syntax.stderr b/src/test/ui/parser/closure-return-syntax.stderr
new file mode 100644
index 000000000..3d16a2067
--- /dev/null
+++ b/src/test/ui/parser/closure-return-syntax.stderr
@@ -0,0 +1,13 @@
+error: expected `{`, found `22`
+ --> $DIR/closure-return-syntax.rs:5:23
+ |
+LL | let x = || -> i32 22;
+ | ^^ expected `{`
+ |
+help: try placing this code inside a block
+ |
+LL | let x = || -> i32 { 22 };
+ | + +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/column-offset-1-based.rs b/src/test/ui/parser/column-offset-1-based.rs
new file mode 100644
index 000000000..0c24478c2
--- /dev/null
+++ b/src/test/ui/parser/column-offset-1-based.rs
@@ -0,0 +1 @@
+# //~ ERROR expected one of `!` or `[`, found `<eof>`
diff --git a/src/test/ui/parser/column-offset-1-based.stderr b/src/test/ui/parser/column-offset-1-based.stderr
new file mode 100644
index 000000000..766d72a0a
--- /dev/null
+++ b/src/test/ui/parser/column-offset-1-based.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `[`, found `<eof>`
+ --> $DIR/column-offset-1-based.rs:1:1
+ |
+LL | #
+ | ^ expected one of `!` or `[`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs
new file mode 100644
index 000000000..53e3c6f96
--- /dev/null
+++ b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.rs
@@ -0,0 +1,15 @@
+struct NInts<const N: usize>([u8; N]);
+impl NInts<const N: usize> {} //~ ERROR unexpected `const` parameter declaration
+
+fn main() {
+ let _: () = 42; //~ ERROR mismatched types
+}
+
+fn banana(a: <T<const N: usize>>::BAR) {}
+//~^ ERROR unexpected `const` parameter declaration
+//~| ERROR cannot find type `T` in this scope
+fn chaenomeles() {
+ path::path::Struct::<const N: usize>()
+ //~^ ERROR unexpected `const` parameter declaration
+ //~| ERROR failed to resolve: use of undeclared crate or module `path`
+}
diff --git a/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr
new file mode 100644
index 000000000..96885d11e
--- /dev/null
+++ b/src/test/ui/parser/const-param-decl-on-type-instead-of-impl.stderr
@@ -0,0 +1,47 @@
+error: unexpected `const` parameter declaration
+ --> $DIR/const-param-decl-on-type-instead-of-impl.rs:2:12
+ |
+LL | impl NInts<const N: usize> {}
+ | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration
+ |
+help: `const` parameters must be declared for the `impl`
+ |
+LL | impl<const N: usize> NInts<N> {}
+ | ++++++++++++++++ ~
+
+error: unexpected `const` parameter declaration
+ --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:17
+ |
+LL | fn banana(a: <T<const N: usize>>::BAR) {}
+ | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration
+
+error: unexpected `const` parameter declaration
+ --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:26
+ |
+LL | path::path::Struct::<const N: usize>()
+ | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration
+
+error[E0433]: failed to resolve: use of undeclared crate or module `path`
+ --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:5
+ |
+LL | path::path::Struct::<const N: usize>()
+ | ^^^^ use of undeclared crate or module `path`
+
+error[E0412]: cannot find type `T` in this scope
+ --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15
+ |
+LL | fn banana(a: <T<const N: usize>>::BAR) {}
+ | ^ not found in this scope
+
+error[E0308]: mismatched types
+ --> $DIR/const-param-decl-on-type-instead-of-impl.rs:5:17
+ |
+LL | let _: () = 42;
+ | -- ^^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0308, E0412, E0433.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
new file mode 100644
index 000000000..afbd13e6f
--- /dev/null
+++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#[cfg(FALSE)]
+fn syntax() {
+ foo::<T = u8, T: Ord, String>();
+ foo::<T = u8, 'a, T: Ord>();
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/default-on-wrong-item-kind.rs b/src/test/ui/parser/default-on-wrong-item-kind.rs
new file mode 100644
index 000000000..98a95cfa3
--- /dev/null
+++ b/src/test/ui/parser/default-on-wrong-item-kind.rs
@@ -0,0 +1,140 @@
+// Test parsing for `default` where it doesn't belong.
+// Specifically, we are interested in kinds of items or items in certain contexts.
+// Also test item kinds in `extern` blocks and associated contexts which are not allowed there.
+
+fn main() {}
+
+#[cfg(FALSE)]
+mod free_items {
+ default extern crate foo; //~ ERROR an extern crate cannot be `default`
+ default use foo; //~ ERROR a `use` import cannot be `default`
+ default static foo: u8; //~ ERROR a static item cannot be `default`
+ default const foo: u8;
+ default fn foo();
+ default mod foo {} //~ ERROR a module cannot be `default`
+ default extern "C" {} //~ ERROR an extern block cannot be `default`
+ default type foo = u8;
+ default enum foo {} //~ ERROR an enum cannot be `default`
+ default struct foo {} //~ ERROR a struct cannot be `default`
+ default union foo {} //~ ERROR a union cannot be `default`
+ default trait foo {} //~ ERROR a trait cannot be `default`
+ default trait foo = Ord; //~ ERROR a trait alias cannot be `default`
+ default impl foo {}
+ default!();
+ default::foo::bar!();
+ default default!(); //~ ERROR an item macro invocation cannot be `default`
+ default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default`
+ default macro foo {} //~ ERROR a macro definition cannot be `default`
+ default macro_rules! foo {} //~ ERROR a macro definition cannot be `default`
+}
+
+#[cfg(FALSE)]
+extern "C" {
+ default extern crate foo; //~ ERROR an extern crate cannot be `default`
+ //~^ ERROR extern crate is not supported in `extern` blocks
+ default use foo; //~ ERROR a `use` import cannot be `default`
+ //~^ ERROR `use` import is not supported in `extern` blocks
+ default static foo: u8; //~ ERROR a static item cannot be `default`
+ default const foo: u8;
+ //~^ ERROR extern items cannot be `const`
+ default fn foo();
+ default mod foo {} //~ ERROR a module cannot be `default`
+ //~^ ERROR module is not supported in `extern` blocks
+ default extern "C" {} //~ ERROR an extern block cannot be `default`
+ //~^ ERROR extern block is not supported in `extern` blocks
+ default type foo = u8;
+ default enum foo {} //~ ERROR an enum cannot be `default`
+ //~^ ERROR enum is not supported in `extern` blocks
+ default struct foo {} //~ ERROR a struct cannot be `default`
+ //~^ ERROR struct is not supported in `extern` blocks
+ default union foo {} //~ ERROR a union cannot be `default`
+ //~^ ERROR union is not supported in `extern` blocks
+ default trait foo {} //~ ERROR a trait cannot be `default`
+ //~^ ERROR trait is not supported in `extern` blocks
+ default trait foo = Ord; //~ ERROR a trait alias cannot be `default`
+ //~^ ERROR trait alias is not supported in `extern` blocks
+ default impl foo {}
+ //~^ ERROR implementation is not supported in `extern` blocks
+ default!();
+ default::foo::bar!();
+ default default!(); //~ ERROR an item macro invocation cannot be `default`
+ default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default`
+ default macro foo {} //~ ERROR a macro definition cannot be `default`
+ //~^ ERROR macro definition is not supported in `extern` blocks
+ default macro_rules! foo {} //~ ERROR a macro definition cannot be `default`
+ //~^ ERROR macro definition is not supported in `extern` blocks
+}
+
+#[cfg(FALSE)]
+impl S {
+ default extern crate foo; //~ ERROR an extern crate cannot be `default`
+ //~^ ERROR extern crate is not supported in `trait`s or `impl`s
+ default use foo; //~ ERROR a `use` import cannot be `default`
+ //~^ ERROR `use` import is not supported in `trait`s or `impl`s
+ default static foo: u8; //~ ERROR a static item cannot be `default`
+ //~^ ERROR associated `static` items are not allowed
+ default const foo: u8;
+ default fn foo();
+ default mod foo {}//~ ERROR a module cannot be `default`
+ //~^ ERROR module is not supported in `trait`s or `impl`s
+ default extern "C" {} //~ ERROR an extern block cannot be `default`
+ //~^ ERROR extern block is not supported in `trait`s or `impl`s
+ default type foo = u8;
+ default enum foo {} //~ ERROR an enum cannot be `default`
+ //~^ ERROR enum is not supported in `trait`s or `impl`s
+ default struct foo {} //~ ERROR a struct cannot be `default`
+ //~^ ERROR struct is not supported in `trait`s or `impl`s
+ default union foo {} //~ ERROR a union cannot be `default`
+ //~^ ERROR union is not supported in `trait`s or `impl`s
+ default trait foo {} //~ ERROR a trait cannot be `default`
+ //~^ ERROR trait is not supported in `trait`s or `impl`s
+ default trait foo = Ord; //~ ERROR a trait alias cannot be `default`
+ //~^ ERROR trait alias is not supported in `trait`s or `impl`s
+ default impl foo {}
+ //~^ ERROR implementation is not supported in `trait`s or `impl`s
+ default!();
+ default::foo::bar!();
+ default default!(); //~ ERROR an item macro invocation cannot be `default`
+ default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default`
+ default macro foo {} //~ ERROR a macro definition cannot be `default`
+ //~^ ERROR macro definition is not supported in `trait`s or `impl`s
+ default macro_rules! foo {} //~ ERROR a macro definition cannot be `default`
+ //~^ ERROR macro definition is not supported in `trait`s or `impl`s
+}
+
+#[cfg(FALSE)]
+trait T {
+ default extern crate foo; //~ ERROR an extern crate cannot be `default`
+ //~^ ERROR extern crate is not supported in `trait`s or `impl`s
+ default use foo; //~ ERROR a `use` import cannot be `default`
+ //~^ ERROR `use` import is not supported in `trait`s or `impl`s
+ default static foo: u8; //~ ERROR a static item cannot be `default`
+ //~^ ERROR associated `static` items are not allowed
+ default const foo: u8;
+ default fn foo();
+ default mod foo {}//~ ERROR a module cannot be `default`
+ //~^ ERROR module is not supported in `trait`s or `impl`s
+ default extern "C" {} //~ ERROR an extern block cannot be `default`
+ //~^ ERROR extern block is not supported in `trait`s or `impl`s
+ default type foo = u8;
+ default enum foo {} //~ ERROR an enum cannot be `default`
+ //~^ ERROR enum is not supported in `trait`s or `impl`s
+ default struct foo {} //~ ERROR a struct cannot be `default`
+ //~^ ERROR struct is not supported in `trait`s or `impl`s
+ default union foo {} //~ ERROR a union cannot be `default`
+ //~^ ERROR union is not supported in `trait`s or `impl`s
+ default trait foo {} //~ ERROR a trait cannot be `default`
+ //~^ ERROR trait is not supported in `trait`s or `impl`s
+ default trait foo = Ord; //~ ERROR a trait alias cannot be `default`
+ //~^ ERROR trait alias is not supported in `trait`s or `impl`s
+ default impl foo {}
+ //~^ ERROR implementation is not supported in `trait`s or `impl`s
+ default!();
+ default::foo::bar!();
+ default default!(); //~ ERROR an item macro invocation cannot be `default`
+ default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default`
+ default macro foo {} //~ ERROR a macro definition cannot be `default`
+ //~^ ERROR macro definition is not supported in `trait`s or `impl`s
+ default macro_rules! foo {} //~ ERROR a macro definition cannot be `default`
+ //~^ ERROR macro definition is not supported in `trait`s or `impl`s
+}
diff --git a/src/test/ui/parser/default-on-wrong-item-kind.stderr b/src/test/ui/parser/default-on-wrong-item-kind.stderr
new file mode 100644
index 000000000..af513f761
--- /dev/null
+++ b/src/test/ui/parser/default-on-wrong-item-kind.stderr
@@ -0,0 +1,760 @@
+error: an extern crate cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:9:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a `use` import cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:10:5
+ |
+LL | default use foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a static item cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:11:5
+ |
+LL | default static foo: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a module cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:14:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an extern block cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:15:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an enum cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:17:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a struct cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:18:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a union cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:19:5
+ |
+LL | default union foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a trait cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:20:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a trait alias cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:21:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:25:5
+ |
+LL | default default!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:26:5
+ |
+LL | default default::foo::bar!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:27:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:28:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an extern crate cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:33:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern crate is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:33:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the extern crate out to a nearby module scope
+
+error: a `use` import cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:35:5
+ |
+LL | default use foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: `use` import is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:35:5
+ |
+LL | default use foo;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the `use` import out to a nearby module scope
+
+error: a static item cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:37:5
+ |
+LL | default static foo: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern items cannot be `const`
+ --> $DIR/default-on-wrong-item-kind.rs:38:19
+ |
+LL | default const foo: u8;
+ | --------------^^^
+ | |
+ | help: try using a static value: `static`
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: a module cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:41:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: module is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:41:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the module out to a nearby module scope
+
+error: an extern block cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:43:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern block is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:43:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the extern block out to a nearby module scope
+
+error: an enum cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:46:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: enum is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:46:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the enum out to a nearby module scope
+
+error: a struct cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:48:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: struct is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:48:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: a union cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:50:5
+ |
+LL | default union foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: union is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:50:5
+ |
+LL | default union foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the union out to a nearby module scope
+
+error: a trait cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:52:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: trait is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:52:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the trait out to a nearby module scope
+
+error: a trait alias cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:54:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: trait alias is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:54:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the trait alias out to a nearby module scope
+
+error: implementation is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:56:5
+ |
+LL | default impl foo {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the implementation out to a nearby module scope
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:60:5
+ |
+LL | default default!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:61:5
+ |
+LL | default default::foo::bar!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:62:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: macro definition is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:62:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the macro definition out to a nearby module scope
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:64:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: macro definition is not supported in `extern` blocks
+ --> $DIR/default-on-wrong-item-kind.rs:64:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the macro definition out to a nearby module scope
+
+error: an extern crate cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:70:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern crate is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:70:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the extern crate out to a nearby module scope
+
+error: a `use` import cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:72:5
+ |
+LL | default use foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: `use` import is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:72:5
+ |
+LL | default use foo;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the `use` import out to a nearby module scope
+
+error: a static item cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:74:5
+ |
+LL | default static foo: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/default-on-wrong-item-kind.rs:74:5
+ |
+LL | default static foo: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a module cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:78:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: module is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:78:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the module out to a nearby module scope
+
+error: an extern block cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:80:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern block is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:80:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the extern block out to a nearby module scope
+
+error: an enum cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:83:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: enum is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:83:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the enum out to a nearby module scope
+
+error: a struct cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:85:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: struct is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:85:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: a union cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:87:5
+ |
+LL | default union foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: union is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:87:5
+ |
+LL | default union foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the union out to a nearby module scope
+
+error: a trait cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:89:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: trait is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:89:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the trait out to a nearby module scope
+
+error: a trait alias cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:91:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: trait alias is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:91:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the trait alias out to a nearby module scope
+
+error: implementation is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:93:5
+ |
+LL | default impl foo {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the implementation out to a nearby module scope
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:97:5
+ |
+LL | default default!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:98:5
+ |
+LL | default default::foo::bar!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:99:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: macro definition is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:99:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the macro definition out to a nearby module scope
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:101:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: macro definition is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:101:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the macro definition out to a nearby module scope
+
+error: an extern crate cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:107:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern crate is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:107:5
+ |
+LL | default extern crate foo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the extern crate out to a nearby module scope
+
+error: a `use` import cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:109:5
+ |
+LL | default use foo;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: `use` import is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:109:5
+ |
+LL | default use foo;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the `use` import out to a nearby module scope
+
+error: a static item cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:111:5
+ |
+LL | default static foo: u8;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: associated `static` items are not allowed
+ --> $DIR/default-on-wrong-item-kind.rs:111:5
+ |
+LL | default static foo: u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a module cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:115:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: module is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:115:5
+ |
+LL | default mod foo {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the module out to a nearby module scope
+
+error: an extern block cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:117:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: extern block is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:117:5
+ |
+LL | default extern "C" {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the extern block out to a nearby module scope
+
+error: an enum cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:120:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: enum is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:120:5
+ |
+LL | default enum foo {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the enum out to a nearby module scope
+
+error: a struct cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:122:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: struct is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:122:5
+ |
+LL | default struct foo {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: a union cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:124:5
+ |
+LL | default union foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: union is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:124:5
+ |
+LL | default union foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the union out to a nearby module scope
+
+error: a trait cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:126:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: trait is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:126:5
+ |
+LL | default trait foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the trait out to a nearby module scope
+
+error: a trait alias cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:128:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: trait alias is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:128:5
+ |
+LL | default trait foo = Ord;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the trait alias out to a nearby module scope
+
+error: implementation is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:130:5
+ |
+LL | default impl foo {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the implementation out to a nearby module scope
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:134:5
+ |
+LL | default default!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: an item macro invocation cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:135:5
+ |
+LL | default default::foo::bar!();
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:136:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: macro definition is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:136:5
+ |
+LL | default macro foo {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the macro definition out to a nearby module scope
+
+error: a macro definition cannot be `default`
+ --> $DIR/default-on-wrong-item-kind.rs:138:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^ `default` because of this
+ |
+ = note: only associated `fn`, `const`, and `type` items can be `default`
+
+error: macro definition is not supported in `trait`s or `impl`s
+ --> $DIR/default-on-wrong-item-kind.rs:138:5
+ |
+LL | default macro_rules! foo {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the macro definition out to a nearby module scope
+
+error: aborting due to 95 previous errors
+
diff --git a/src/test/ui/parser/default-unmatched-assoc.rs b/src/test/ui/parser/default-unmatched-assoc.rs
new file mode 100644
index 000000000..168ea3e76
--- /dev/null
+++ b/src/test/ui/parser/default-unmatched-assoc.rs
@@ -0,0 +1,16 @@
+fn main() {}
+
+trait Foo {
+ default!(); //~ ERROR cannot find macro `default` in this scope
+ default do
+ //~^ ERROR `default` is not followed by an item
+ //~| ERROR non-item in item list
+}
+
+struct S;
+impl S {
+ default!(); //~ ERROR cannot find macro `default` in this scope
+ default do
+ //~^ ERROR `default` is not followed by an item
+ //~| ERROR non-item in item list
+}
diff --git a/src/test/ui/parser/default-unmatched-assoc.stderr b/src/test/ui/parser/default-unmatched-assoc.stderr
new file mode 100644
index 000000000..ee35fded9
--- /dev/null
+++ b/src/test/ui/parser/default-unmatched-assoc.stderr
@@ -0,0 +1,54 @@
+error: `default` is not followed by an item
+ --> $DIR/default-unmatched-assoc.rs:5:5
+ |
+LL | default do
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: non-item in item list
+ --> $DIR/default-unmatched-assoc.rs:5:13
+ |
+LL | trait Foo {
+ | - item list starts here
+LL | default!();
+LL | default do
+ | ^^ non-item starts here
+...
+LL | }
+ | - item list ends here
+
+error: `default` is not followed by an item
+ --> $DIR/default-unmatched-assoc.rs:13:5
+ |
+LL | default do
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: non-item in item list
+ --> $DIR/default-unmatched-assoc.rs:13:13
+ |
+LL | impl S {
+ | - item list starts here
+LL | default!();
+LL | default do
+ | ^^ non-item starts here
+...
+LL | }
+ | - item list ends here
+
+error: cannot find macro `default` in this scope
+ --> $DIR/default-unmatched-assoc.rs:4:5
+ |
+LL | default!();
+ | ^^^^^^^
+
+error: cannot find macro `default` in this scope
+ --> $DIR/default-unmatched-assoc.rs:12:5
+ |
+LL | default!();
+ | ^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/default-unmatched-extern.rs b/src/test/ui/parser/default-unmatched-extern.rs
new file mode 100644
index 000000000..8d0ea590f
--- /dev/null
+++ b/src/test/ui/parser/default-unmatched-extern.rs
@@ -0,0 +1,8 @@
+fn main() {}
+
+extern "C" {
+ default!(); //~ ERROR cannot find macro `default` in this scope
+ default do
+ //~^ ERROR `default` is not followed by an item
+ //~| ERROR non-item in item list
+}
diff --git a/src/test/ui/parser/default-unmatched-extern.stderr b/src/test/ui/parser/default-unmatched-extern.stderr
new file mode 100644
index 000000000..bb4efd516
--- /dev/null
+++ b/src/test/ui/parser/default-unmatched-extern.stderr
@@ -0,0 +1,28 @@
+error: `default` is not followed by an item
+ --> $DIR/default-unmatched-extern.rs:5:5
+ |
+LL | default do
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: non-item in item list
+ --> $DIR/default-unmatched-extern.rs:5:13
+ |
+LL | extern "C" {
+ | - item list starts here
+LL | default!();
+LL | default do
+ | ^^ non-item starts here
+...
+LL | }
+ | - item list ends here
+
+error: cannot find macro `default` in this scope
+ --> $DIR/default-unmatched-extern.rs:4:5
+ |
+LL | default!();
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/default-unmatched.rs b/src/test/ui/parser/default-unmatched.rs
new file mode 100644
index 000000000..49346e5c6
--- /dev/null
+++ b/src/test/ui/parser/default-unmatched.rs
@@ -0,0 +1,6 @@
+mod foo {
+ default!(); // OK.
+ default do
+ //~^ ERROR `default` is not followed by an item
+ //~| ERROR expected item, found reserved keyword `do`
+}
diff --git a/src/test/ui/parser/default-unmatched.stderr b/src/test/ui/parser/default-unmatched.stderr
new file mode 100644
index 000000000..331e003f6
--- /dev/null
+++ b/src/test/ui/parser/default-unmatched.stderr
@@ -0,0 +1,16 @@
+error: `default` is not followed by an item
+ --> $DIR/default-unmatched.rs:3:5
+ |
+LL | default do
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: expected item, found reserved keyword `do`
+ --> $DIR/default-unmatched.rs:3:13
+ |
+LL | default do
+ | ^^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/default.rs b/src/test/ui/parser/default.rs
new file mode 100644
index 000000000..52338c1f1
--- /dev/null
+++ b/src/test/ui/parser/default.rs
@@ -0,0 +1,28 @@
+// Test successful and unsuccessful parsing of the `default` contextual keyword
+
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ fn foo<T: Default>() -> T;
+}
+
+impl Foo for u8 {
+ default fn foo<T: Default>() -> T {
+ T::default()
+ }
+}
+
+impl Foo for u16 {
+ pub default fn foo<T: Default>() -> T { //~ ERROR unnecessary visibility qualifier
+ T::default()
+ }
+}
+
+impl Foo for u32 { //~ ERROR not all trait items implemented, missing: `foo`
+ default pub fn foo<T: Default>() -> T { T::default() }
+ //~^ ERROR `default` is not followed by an item
+ //~| ERROR non-item in item list
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr
new file mode 100644
index 000000000..5b763ae72
--- /dev/null
+++ b/src/test/ui/parser/default.stderr
@@ -0,0 +1,48 @@
+error: `default` is not followed by an item
+ --> $DIR/default.rs:23:5
+ |
+LL | default pub fn foo<T: Default>() -> T { T::default() }
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: non-item in item list
+ --> $DIR/default.rs:23:13
+ |
+LL | impl Foo for u32 {
+ | - item list starts here
+LL | default pub fn foo<T: Default>() -> T { T::default() }
+ | ^^^ non-item starts here
+...
+LL | }
+ | - item list ends here
+
+error[E0449]: unnecessary visibility qualifier
+ --> $DIR/default.rs:17:5
+ |
+LL | pub default fn foo<T: Default>() -> T {
+ | ^^^ `pub` not permitted here because it's implied
+
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/default.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+
+error[E0046]: not all trait items implemented, missing: `foo`
+ --> $DIR/default.rs:22:1
+ |
+LL | fn foo<T: Default>() -> T;
+ | -------------------------- `foo` from trait
+...
+LL | impl Foo for u32 {
+ | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0046, E0449.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/src/test/ui/parser/do-catch-suggests-try.rs b/src/test/ui/parser/do-catch-suggests-try.rs
new file mode 100644
index 000000000..f64568d06
--- /dev/null
+++ b/src/test/ui/parser/do-catch-suggests-try.rs
@@ -0,0 +1,10 @@
+#![feature(try_blocks)]
+
+fn main() {
+ let _: Option<()> = do catch {};
+ //~^ ERROR found removed `do catch` syntax
+ //~| replace with the new syntax
+ //~| following RFC #2388, the new non-placeholder syntax is `try`
+
+ let _recovery_witness: () = 1; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/do-catch-suggests-try.stderr b/src/test/ui/parser/do-catch-suggests-try.stderr
new file mode 100644
index 000000000..cd8907b7e
--- /dev/null
+++ b/src/test/ui/parser/do-catch-suggests-try.stderr
@@ -0,0 +1,19 @@
+error: found removed `do catch` syntax
+ --> $DIR/do-catch-suggests-try.rs:4:25
+ |
+LL | let _: Option<()> = do catch {};
+ | ^^^^^^^^ help: replace with the new syntax: `try`
+ |
+ = note: following RFC #2388, the new non-placeholder syntax is `try`
+
+error[E0308]: mismatched types
+ --> $DIR/do-catch-suggests-try.rs:9:33
+ |
+LL | let _recovery_witness: () = 1;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/doc-after-struct-field.rs b/src/test/ui/parser/doc-after-struct-field.rs
new file mode 100644
index 000000000..5b6f08036
--- /dev/null
+++ b/src/test/ui/parser/doc-after-struct-field.rs
@@ -0,0 +1,16 @@
+struct X {
+ a: u8 /** document a */,
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+}
+
+struct Y {
+ a: u8 /// document a
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+}
+
+fn main() {
+ let x = X { a: 1 };
+ let y = Y { a: 1 };
+}
diff --git a/src/test/ui/parser/doc-after-struct-field.stderr b/src/test/ui/parser/doc-after-struct-field.stderr
new file mode 100644
index 000000000..e3b32a7f0
--- /dev/null
+++ b/src/test/ui/parser/doc-after-struct-field.stderr
@@ -0,0 +1,19 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-after-struct-field.rs:2:11
+ |
+LL | a: u8 /** document a */,
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-after-struct-field.rs:8:11
+ |
+LL | a: u8 /// document a
+ | ^^^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/doc-before-attr.rs b/src/test/ui/parser/doc-before-attr.rs
new file mode 100644
index 000000000..c4125a09f
--- /dev/null
+++ b/src/test/ui/parser/doc-before-attr.rs
@@ -0,0 +1,4 @@
+fn main() {}
+
+/// hi
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/ui/parser/doc-before-attr.stderr b/src/test/ui/parser/doc-before-attr.stderr
new file mode 100644
index 000000000..14fd01af2
--- /dev/null
+++ b/src/test/ui/parser/doc-before-attr.stderr
@@ -0,0 +1,10 @@
+error: expected item after attributes
+ --> $DIR/doc-before-attr.rs:4:1
+ |
+LL | /// hi
+ | ------ other attributes here
+LL | #[derive(Debug)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/doc-before-eof.rs b/src/test/ui/parser/doc-before-eof.rs
new file mode 100644
index 000000000..b31836e95
--- /dev/null
+++ b/src/test/ui/parser/doc-before-eof.rs
@@ -0,0 +1,3 @@
+fn main() {}
+
+/// hi //~ERROR expected item after doc comment
diff --git a/src/test/ui/parser/doc-before-eof.stderr b/src/test/ui/parser/doc-before-eof.stderr
new file mode 100644
index 000000000..827566267
--- /dev/null
+++ b/src/test/ui/parser/doc-before-eof.stderr
@@ -0,0 +1,8 @@
+error: expected item after doc comment
+ --> $DIR/doc-before-eof.rs:3:1
+ |
+LL | /// hi
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/doc-before-extern-rbrace.rs b/src/test/ui/parser/doc-before-extern-rbrace.rs
new file mode 100644
index 000000000..515c90ed4
--- /dev/null
+++ b/src/test/ui/parser/doc-before-extern-rbrace.rs
@@ -0,0 +1,6 @@
+fn main() {}
+
+extern "C" {
+ /// hi
+ //~^ ERROR found a documentation comment that doesn't document anything
+}
diff --git a/src/test/ui/parser/doc-before-extern-rbrace.stderr b/src/test/ui/parser/doc-before-extern-rbrace.stderr
new file mode 100644
index 000000000..0edceb268
--- /dev/null
+++ b/src/test/ui/parser/doc-before-extern-rbrace.stderr
@@ -0,0 +1,11 @@
+error[E0584]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-before-extern-rbrace.rs:4:5
+ |
+LL | /// hi
+ | ^^^^^^ this doc comment doesn't document anything
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0584`.
diff --git a/src/test/ui/parser/doc-before-fn-rbrace.rs b/src/test/ui/parser/doc-before-fn-rbrace.rs
new file mode 100644
index 000000000..eb355136f
--- /dev/null
+++ b/src/test/ui/parser/doc-before-fn-rbrace.rs
@@ -0,0 +1,5 @@
+fn main() {
+ /// document
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+}
diff --git a/src/test/ui/parser/doc-before-fn-rbrace.stderr b/src/test/ui/parser/doc-before-fn-rbrace.stderr
new file mode 100644
index 000000000..56241de70
--- /dev/null
+++ b/src/test/ui/parser/doc-before-fn-rbrace.stderr
@@ -0,0 +1,11 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-before-fn-rbrace.rs:2:5
+ |
+LL | /// document
+ | ^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/doc-before-identifier.rs b/src/test/ui/parser/doc-before-identifier.rs
new file mode 100644
index 000000000..76263ad92
--- /dev/null
+++ b/src/test/ui/parser/doc-before-identifier.rs
@@ -0,0 +1,7 @@
+fn /// document
+foo() {}
+//~^^ ERROR expected identifier, found doc comment `/// document`
+
+fn main() {
+ foo();
+}
diff --git a/src/test/ui/parser/doc-before-identifier.stderr b/src/test/ui/parser/doc-before-identifier.stderr
new file mode 100644
index 000000000..940d293b6
--- /dev/null
+++ b/src/test/ui/parser/doc-before-identifier.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found doc comment `/// document`
+ --> $DIR/doc-before-identifier.rs:1:4
+ |
+LL | fn /// document
+ | ^^^^^^^^^^^^ expected identifier, found doc comment
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/doc-before-mod-rbrace.rs b/src/test/ui/parser/doc-before-mod-rbrace.rs
new file mode 100644
index 000000000..c65a0a931
--- /dev/null
+++ b/src/test/ui/parser/doc-before-mod-rbrace.rs
@@ -0,0 +1,6 @@
+mod Foo {
+ /// document
+ //~^ ERROR expected item after doc comment
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/doc-before-mod-rbrace.stderr b/src/test/ui/parser/doc-before-mod-rbrace.stderr
new file mode 100644
index 000000000..d5749c66c
--- /dev/null
+++ b/src/test/ui/parser/doc-before-mod-rbrace.stderr
@@ -0,0 +1,8 @@
+error: expected item after doc comment
+ --> $DIR/doc-before-mod-rbrace.rs:2:5
+ |
+LL | /// document
+ | ^^^^^^^^^^^^ this doc comment doesn't document anything
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/doc-before-rbrace.rs b/src/test/ui/parser/doc-before-rbrace.rs
new file mode 100644
index 000000000..8ff946344
--- /dev/null
+++ b/src/test/ui/parser/doc-before-rbrace.rs
@@ -0,0 +1,5 @@
+fn main() {
+ println!("Hi"); /// hi
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+}
diff --git a/src/test/ui/parser/doc-before-rbrace.stderr b/src/test/ui/parser/doc-before-rbrace.stderr
new file mode 100644
index 000000000..55719cf64
--- /dev/null
+++ b/src/test/ui/parser/doc-before-rbrace.stderr
@@ -0,0 +1,11 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-before-rbrace.rs:2:21
+ |
+LL | println!("Hi"); /// hi
+ | ^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/doc-before-semi.rs b/src/test/ui/parser/doc-before-semi.rs
new file mode 100644
index 000000000..405a7e1e2
--- /dev/null
+++ b/src/test/ui/parser/doc-before-semi.rs
@@ -0,0 +1,6 @@
+fn main() {
+ /// hi
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+ ;
+}
diff --git a/src/test/ui/parser/doc-before-semi.stderr b/src/test/ui/parser/doc-before-semi.stderr
new file mode 100644
index 000000000..e6bade18d
--- /dev/null
+++ b/src/test/ui/parser/doc-before-semi.stderr
@@ -0,0 +1,11 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-before-semi.rs:2:5
+ |
+LL | /// hi
+ | ^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.rs b/src/test/ui/parser/doc-before-struct-rbrace-1.rs
new file mode 100644
index 000000000..3866a3105
--- /dev/null
+++ b/src/test/ui/parser/doc-before-struct-rbrace-1.rs
@@ -0,0 +1,10 @@
+struct X {
+ a: u8,
+ /// document
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+}
+
+fn main() {
+ let y = X {a: 1};
+}
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
new file mode 100644
index 000000000..19f906773
--- /dev/null
+++ b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
@@ -0,0 +1,11 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-before-struct-rbrace-1.rs:3:5
+ |
+LL | /// document
+ | ^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.rs b/src/test/ui/parser/doc-before-struct-rbrace-2.rs
new file mode 100644
index 000000000..dda138f1a
--- /dev/null
+++ b/src/test/ui/parser/doc-before-struct-rbrace-2.rs
@@ -0,0 +1,9 @@
+struct X {
+ a: u8 /// document
+ //~^ ERROR found a documentation comment that doesn't document anything
+ //~| HELP maybe a comment was intended
+}
+
+fn main() {
+ let y = X {a: 1};
+}
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.stderr b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr
new file mode 100644
index 000000000..b25ccab79
--- /dev/null
+++ b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr
@@ -0,0 +1,11 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-before-struct-rbrace-2.rs:2:11
+ |
+LL | a: u8 /// document
+ | ^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/doc-comment-in-if-statement.rs b/src/test/ui/parser/doc-comment-in-if-statement.rs
new file mode 100644
index 000000000..343eac1b8
--- /dev/null
+++ b/src/test/ui/parser/doc-comment-in-if-statement.rs
@@ -0,0 +1,5 @@
+fn main() {
+ if true /*!*/ {}
+ //~^ ERROR outer attributes are not allowed on
+ //~| ERROR expected outer doc comment
+}
diff --git a/src/test/ui/parser/doc-comment-in-if-statement.stderr b/src/test/ui/parser/doc-comment-in-if-statement.stderr
new file mode 100644
index 000000000..fc0bc5073
--- /dev/null
+++ b/src/test/ui/parser/doc-comment-in-if-statement.stderr
@@ -0,0 +1,25 @@
+error[E0753]: expected outer doc comment
+ --> $DIR/doc-comment-in-if-statement.rs:2:13
+ |
+LL | if true /*!*/ {}
+ | ^^^^^
+ |
+ = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
+help: you might have meant to write a regular comment
+ |
+LL - if true /*!*/ {}
+LL + if true /**/ {}
+ |
+
+error: outer attributes are not allowed on `if` and `else` branches
+ --> $DIR/doc-comment-in-if-statement.rs:2:13
+ |
+LL | if true /*!*/ {}
+ | -- ^^^^^ -- the attributes are attached to this branch
+ | | |
+ | | help: remove the attributes
+ | the branch belongs to this `if`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0753`.
diff --git a/src/test/ui/parser/doc-comment-in-stmt.rs b/src/test/ui/parser/doc-comment-in-stmt.rs
new file mode 100644
index 000000000..b02df1321
--- /dev/null
+++ b/src/test/ui/parser/doc-comment-in-stmt.rs
@@ -0,0 +1,20 @@
+fn foo() -> bool {
+ false
+ //!self.allow_ty_infer()
+ //~^ ERROR found doc comment
+}
+
+fn bar() -> bool {
+ false
+ /*! bar */ //~ ERROR found doc comment
+}
+
+fn baz() -> i32 {
+ 1 /** baz */ //~ ERROR found doc comment
+}
+
+fn quux() -> i32 {
+ 2 /*! quux */ //~ ERROR found doc comment
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/doc-comment-in-stmt.stderr b/src/test/ui/parser/doc-comment-in-stmt.stderr
new file mode 100644
index 000000000..febfb600c
--- /dev/null
+++ b/src/test/ui/parser/doc-comment-in-stmt.stderr
@@ -0,0 +1,50 @@
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `//!self.allow_ty_infer()`
+ --> $DIR/doc-comment-in-stmt.rs:3:5
+ |
+LL | false
+ | - expected one of `.`, `;`, `?`, `}`, or an operator
+LL | //!self.allow_ty_infer()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected token
+ |
+help: add a space before `!` to use a regular comment
+ |
+LL | // !self.allow_ty_infer()
+ | ~~~~
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! bar */`
+ --> $DIR/doc-comment-in-stmt.rs:9:5
+ |
+LL | false
+ | - expected one of `.`, `;`, `?`, `}`, or an operator
+LL | /*! bar */
+ | ^^^^^^^^^^ unexpected token
+ |
+help: add a space before `!` to use a regular comment
+ |
+LL | /* ! bar */
+ | ~~~~
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/** baz */`
+ --> $DIR/doc-comment-in-stmt.rs:13:7
+ |
+LL | 1 /** baz */
+ | ^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+ |
+help: add a space before `*` to use a regular comment
+ |
+LL | 1 /* * baz */
+ | ~~~~
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! quux */`
+ --> $DIR/doc-comment-in-stmt.rs:17:7
+ |
+LL | 2 /*! quux */
+ | ^^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+ |
+help: add a space before `!` to use a regular comment
+ |
+LL | 2 /* ! quux */
+ | ~~~~
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/doc-inside-trait-item.rs b/src/test/ui/parser/doc-inside-trait-item.rs
new file mode 100644
index 000000000..87b501bd2
--- /dev/null
+++ b/src/test/ui/parser/doc-inside-trait-item.rs
@@ -0,0 +1,6 @@
+trait User{
+ fn test();
+ /// empty doc
+ //~^ ERROR found a documentation comment that doesn't document anything
+}
+fn main() {}
diff --git a/src/test/ui/parser/doc-inside-trait-item.stderr b/src/test/ui/parser/doc-inside-trait-item.stderr
new file mode 100644
index 000000000..246255a0a
--- /dev/null
+++ b/src/test/ui/parser/doc-inside-trait-item.stderr
@@ -0,0 +1,11 @@
+error[E0584]: found a documentation comment that doesn't document anything
+ --> $DIR/doc-inside-trait-item.rs:3:5
+ |
+LL | /// empty doc
+ | ^^^^^^^^^^^^^ this doc comment doesn't document anything
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0584`.
diff --git a/src/test/ui/parser/dotdotdot-expr.rs b/src/test/ui/parser/dotdotdot-expr.rs
new file mode 100644
index 000000000..d842fb6e0
--- /dev/null
+++ b/src/test/ui/parser/dotdotdot-expr.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let _redemptive = 1...21;
+ //~^ ERROR unexpected token
+}
diff --git a/src/test/ui/parser/dotdotdot-expr.stderr b/src/test/ui/parser/dotdotdot-expr.stderr
new file mode 100644
index 000000000..e7203f24d
--- /dev/null
+++ b/src/test/ui/parser/dotdotdot-expr.stderr
@@ -0,0 +1,17 @@
+error: unexpected token: `...`
+ --> $DIR/dotdotdot-expr.rs:2:24
+ |
+LL | let _redemptive = 1...21;
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | let _redemptive = 1..21;
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | let _redemptive = 1..=21;
+ | ~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs
new file mode 100644
index 000000000..54955944c
--- /dev/null
+++ b/src/test/ui/parser/duplicate-visibility.rs
@@ -0,0 +1,9 @@
+fn main() {}
+
+extern "C" { //~ NOTE while parsing this item list starting here
+ pub pub fn foo();
+ //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
+ //~| NOTE expected one of 8 possible tokens
+ //~| HELP there is already a visibility modifier, remove one
+ //~| NOTE explicit visibility first seen here
+} //~ NOTE the item list ends here
diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr
new file mode 100644
index 000000000..8ecebf01f
--- /dev/null
+++ b/src/test/ui/parser/duplicate-visibility.stderr
@@ -0,0 +1,22 @@
+error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
+ --> $DIR/duplicate-visibility.rs:4:9
+ |
+LL | extern "C" {
+ | - while parsing this item list starting here
+LL | pub pub fn foo();
+ | ^^^
+ | |
+ | expected one of 8 possible tokens
+ | help: there is already a visibility modifier, remove one
+...
+LL | }
+ | - the item list ends here
+ |
+note: explicit visibility first seen here
+ --> $DIR/duplicate-visibility.rs:4:5
+ |
+LL | pub pub fn foo();
+ | ^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/duplicate-where-clauses.rs b/src/test/ui/parser/duplicate-where-clauses.rs
new file mode 100644
index 000000000..9eb2ffb06
--- /dev/null
+++ b/src/test/ui/parser/duplicate-where-clauses.rs
@@ -0,0 +1,19 @@
+struct A where (): Sized where (): Sized {}
+//~^ ERROR cannot define duplicate `where` clauses on an item
+
+fn b() where (): Sized where (): Sized {}
+//~^ ERROR cannot define duplicate `where` clauses on an item
+
+enum C where (): Sized where (): Sized {}
+//~^ ERROR cannot define duplicate `where` clauses on an item
+
+struct D where (): Sized, where (): Sized {}
+//~^ ERROR cannot define duplicate `where` clauses on an item
+
+fn e() where (): Sized, where (): Sized {}
+//~^ ERROR cannot define duplicate `where` clauses on an item
+
+enum F where (): Sized, where (): Sized {}
+//~^ ERROR cannot define duplicate `where` clauses on an item
+
+fn main() {}
diff --git a/src/test/ui/parser/duplicate-where-clauses.stderr b/src/test/ui/parser/duplicate-where-clauses.stderr
new file mode 100644
index 000000000..8250d4f1e
--- /dev/null
+++ b/src/test/ui/parser/duplicate-where-clauses.stderr
@@ -0,0 +1,80 @@
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clauses.rs:1:32
+ |
+LL | struct A where (): Sized where (): Sized {}
+ | - ^
+ | |
+ | previous `where` clause starts here
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | struct A where (): Sized, (): Sized {}
+ | ~
+
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clauses.rs:4:30
+ |
+LL | fn b() where (): Sized where (): Sized {}
+ | - ^
+ | |
+ | previous `where` clause starts here
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | fn b() where (): Sized, (): Sized {}
+ | ~
+
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clauses.rs:7:30
+ |
+LL | enum C where (): Sized where (): Sized {}
+ | - ^
+ | |
+ | previous `where` clause starts here
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | enum C where (): Sized, (): Sized {}
+ | ~
+
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clauses.rs:10:33
+ |
+LL | struct D where (): Sized, where (): Sized {}
+ | - ^
+ | |
+ | previous `where` clause starts here
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | struct D where (): Sized, (): Sized {}
+ | ~
+
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clauses.rs:13:31
+ |
+LL | fn e() where (): Sized, where (): Sized {}
+ | - ^
+ | |
+ | previous `where` clause starts here
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | fn e() where (): Sized, (): Sized {}
+ | ~
+
+error: cannot define duplicate `where` clauses on an item
+ --> $DIR/duplicate-where-clauses.rs:16:31
+ |
+LL | enum F where (): Sized, where (): Sized {}
+ | - ^
+ | |
+ | previous `where` clause starts here
+ |
+help: consider joining the two `where` clauses into one
+ |
+LL | enum F where (): Sized, (): Sized {}
+ | ~
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/dyn-trait-compatibility.rs b/src/test/ui/parser/dyn-trait-compatibility.rs
new file mode 100644
index 000000000..d2b02cc2a
--- /dev/null
+++ b/src/test/ui/parser/dyn-trait-compatibility.rs
@@ -0,0 +1,14 @@
+type A0 = dyn;
+//~^ ERROR cannot find type `dyn` in this scope
+type A1 = dyn::dyn;
+//~^ ERROR use of undeclared crate or module `dyn`
+type A2 = dyn<dyn, dyn>;
+//~^ ERROR cannot find type `dyn` in this scope
+//~| ERROR cannot find type `dyn` in this scope
+//~| ERROR cannot find type `dyn` in this scope
+type A3 = dyn<<dyn as dyn>::dyn>;
+//~^ ERROR cannot find type `dyn` in this scope
+//~| ERROR cannot find type `dyn` in this scope
+//~| ERROR use of undeclared crate or module `dyn`
+
+fn main() {}
diff --git a/src/test/ui/parser/dyn-trait-compatibility.stderr b/src/test/ui/parser/dyn-trait-compatibility.stderr
new file mode 100644
index 000000000..9218ae9d5
--- /dev/null
+++ b/src/test/ui/parser/dyn-trait-compatibility.stderr
@@ -0,0 +1,58 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
+ --> $DIR/dyn-trait-compatibility.rs:3:11
+ |
+LL | type A1 = dyn::dyn;
+ | ^^^ use of undeclared crate or module `dyn`
+
+error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
+ --> $DIR/dyn-trait-compatibility.rs:9:23
+ |
+LL | type A3 = dyn<<dyn as dyn>::dyn>;
+ | ^^^ use of undeclared crate or module `dyn`
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/dyn-trait-compatibility.rs:1:11
+ |
+LL | type A0 = dyn;
+ | ^^^ not found in this scope
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/dyn-trait-compatibility.rs:5:11
+ |
+LL | type A2 = dyn<dyn, dyn>;
+ | ^^^ not found in this scope
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/dyn-trait-compatibility.rs:5:15
+ |
+LL | type A2 = dyn<dyn, dyn>;
+ | - ^^^ not found in this scope
+ | |
+ | help: you might be missing a type parameter: `<dyn>`
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/dyn-trait-compatibility.rs:5:20
+ |
+LL | type A2 = dyn<dyn, dyn>;
+ | - ^^^ not found in this scope
+ | |
+ | help: you might be missing a type parameter: `<dyn>`
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/dyn-trait-compatibility.rs:9:11
+ |
+LL | type A3 = dyn<<dyn as dyn>::dyn>;
+ | ^^^ not found in this scope
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/dyn-trait-compatibility.rs:9:16
+ |
+LL | type A3 = dyn<<dyn as dyn>::dyn>;
+ | - ^^^ not found in this scope
+ | |
+ | help: you might be missing a type parameter: `<dyn>`
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0412, E0433.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/else-no-if.rs b/src/test/ui/parser/else-no-if.rs
new file mode 100644
index 000000000..f0b40ecde
--- /dev/null
+++ b/src/test/ui/parser/else-no-if.rs
@@ -0,0 +1,32 @@
+fn foo() {
+ if true {
+ } else false {
+ //~^ ERROR expected `{`, found keyword `false`
+ }
+}
+
+fn foo2() {
+ if true {
+ } else falsy() {
+ //~^ ERROR expected `{`, found `falsy`
+ }
+}
+
+fn foo3() {
+ if true {
+ } else falsy();
+ //~^ ERROR expected `{`, found `falsy`
+}
+
+fn foo4() {
+ if true {
+ } else loop{}
+ //~^ ERROR expected `{`, found keyword `loop`
+ {}
+}
+
+fn falsy() -> bool {
+ false
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/else-no-if.stderr b/src/test/ui/parser/else-no-if.stderr
new file mode 100644
index 000000000..b9c1a7527
--- /dev/null
+++ b/src/test/ui/parser/else-no-if.stderr
@@ -0,0 +1,50 @@
+error: expected `{`, found keyword `false`
+ --> $DIR/else-no-if.rs:3:12
+ |
+LL | } else false {
+ | ---- ^^^^^
+ | |
+ | expected an `if` or a block after this `else`
+ |
+help: add an `if` if this is the condition of a chained `else if` statement
+ |
+LL | } else if false {
+ | ++
+
+error: expected `{`, found `falsy`
+ --> $DIR/else-no-if.rs:10:12
+ |
+LL | } else falsy() {
+ | ---- ^^^^^
+ | |
+ | expected an `if` or a block after this `else`
+ |
+help: add an `if` if this is the condition of a chained `else if` statement
+ |
+LL | } else if falsy() {
+ | ++
+
+error: expected `{`, found `falsy`
+ --> $DIR/else-no-if.rs:17:12
+ |
+LL | } else falsy();
+ | ^^^^^ expected `{`
+ |
+help: try placing this code inside a block
+ |
+LL | } else { falsy() };
+ | + +
+
+error: expected `{`, found keyword `loop`
+ --> $DIR/else-no-if.rs:23:12
+ |
+LL | } else loop{}
+ | ^^^^ expected `{`
+ |
+help: try placing this code inside a block
+ |
+LL | } else { loop{} }
+ | + +
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/emoji-identifiers.rs b/src/test/ui/parser/emoji-identifiers.rs
new file mode 100644
index 000000000..b50c046bc
--- /dev/null
+++ b/src/test/ui/parser/emoji-identifiers.rs
@@ -0,0 +1,19 @@
+struct ABig👩‍👩‍👧‍👧Family; //~ ERROR identifiers cannot contain emoji
+struct 👀; //~ ERROR identifiers cannot contain emoji
+impl 👀 {
+ fn full_of_✨() -> 👀 { //~ ERROR identifiers cannot contain emoji
+ 👀
+ }
+}
+fn i_like_to_😅_a_lot() -> 👀 { //~ ERROR identifiers cannot contain emoji
+ 👀::full_of✨() //~ ERROR no function or associated item named `full_of✨` found for struct `👀`
+ //~^ ERROR identifiers cannot contain emoji
+}
+fn main() {
+ let _ = i_like_to_😄_a_lot() ➖ 4; //~ ERROR cannot find function `i_like_to_😄_a_lot` in this scope
+ //~^ ERROR identifiers cannot contain emoji
+ //~| ERROR unknown start of token: \u{2796}
+
+ let 🦀 = 1;//~ ERROR Ferris cannot be used as an identifier
+ dbg!(🦀);
+}
diff --git a/src/test/ui/parser/emoji-identifiers.stderr b/src/test/ui/parser/emoji-identifiers.stderr
new file mode 100644
index 000000000..2550dc3d3
--- /dev/null
+++ b/src/test/ui/parser/emoji-identifiers.stderr
@@ -0,0 +1,91 @@
+error: unknown start of token: \u{2796}
+ --> $DIR/emoji-identifiers.rs:13:33
+ |
+LL | let _ = i_like_to_😄_a_lot() ➖ 4;
+ | ^^
+ |
+help: Unicode character '➖' (Heavy Minus Sign) looks like '-' (Minus/Hyphen), but it is not
+ |
+LL | let _ = i_like_to_😄_a_lot() - 4;
+ | ~
+
+error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope
+ --> $DIR/emoji-identifiers.rs:13:13
+ |
+LL | fn i_like_to_😅_a_lot() -> 👀 {
+ | ----------------------------- similarly named function `i_like_to_😅_a_lot` defined here
+...
+LL | let _ = i_like_to_😄_a_lot() ➖ 4;
+ | ^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `i_like_to_😅_a_lot`
+
+error: Ferris cannot be used as an identifier
+ --> $DIR/emoji-identifiers.rs:17:9
+ |
+LL | let 🦀 = 1;
+ | ^^ help: try using their name instead: `ferris`
+LL | dbg!(🦀);
+ | ^^
+
+error: identifiers cannot contain emoji: `ABig👩👩👧👧Family`
+ --> $DIR/emoji-identifiers.rs:1:8
+ |
+LL | struct ABig👩👩👧👧Family;
+ | ^^^^^^^^^^^^^^^^^^
+
+error: identifiers cannot contain emoji: `👀`
+ --> $DIR/emoji-identifiers.rs:2:8
+ |
+LL | struct 👀;
+ | ^^
+LL | impl 👀 {
+ | ^^
+LL | fn full_of_✨() -> 👀 {
+ | ^^
+LL | 👀
+ | ^^
+...
+LL | fn i_like_to_😅_a_lot() -> 👀 {
+ | ^^
+LL | 👀::full_of✨()
+ | ^^
+
+error: identifiers cannot contain emoji: `full_of_✨`
+ --> $DIR/emoji-identifiers.rs:4:8
+ |
+LL | fn full_of_✨() -> 👀 {
+ | ^^^^^^^^^^
+
+error: identifiers cannot contain emoji: `i_like_to_😅_a_lot`
+ --> $DIR/emoji-identifiers.rs:8:4
+ |
+LL | fn i_like_to_😅_a_lot() -> 👀 {
+ | ^^^^^^^^^^^^^^^^^^
+
+error: identifiers cannot contain emoji: `full_of✨`
+ --> $DIR/emoji-identifiers.rs:9:8
+ |
+LL | 👀::full_of✨()
+ | ^^^^^^^^^
+
+error: identifiers cannot contain emoji: `i_like_to_😄_a_lot`
+ --> $DIR/emoji-identifiers.rs:13:13
+ |
+LL | let _ = i_like_to_😄_a_lot() ➖ 4;
+ | ^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no function or associated item named `full_of✨` found for struct `👀` in the current scope
+ --> $DIR/emoji-identifiers.rs:9:8
+ |
+LL | struct 👀;
+ | --------- function or associated item `full_of✨` not found for this struct
+...
+LL | 👀::full_of✨()
+ | ^^^^^^^^^
+ | |
+ | function or associated item not found in `👀`
+ | help: there is an associated function with a similar name: `full_of_✨`
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0425, E0599.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/empty-impl-semicolon.rs b/src/test/ui/parser/empty-impl-semicolon.rs
new file mode 100644
index 000000000..207ebef64
--- /dev/null
+++ b/src/test/ui/parser/empty-impl-semicolon.rs
@@ -0,0 +1 @@
+impl Foo; //~ ERROR expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;`
diff --git a/src/test/ui/parser/empty-impl-semicolon.stderr b/src/test/ui/parser/empty-impl-semicolon.stderr
new file mode 100644
index 000000000..398eb5c89
--- /dev/null
+++ b/src/test/ui/parser/empty-impl-semicolon.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;`
+ --> $DIR/empty-impl-semicolon.rs:1:9
+ |
+LL | impl Foo;
+ | ^ expected one of 8 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/expr-as-stmt-2.rs b/src/test/ui/parser/expr-as-stmt-2.rs
new file mode 100644
index 000000000..3a18bdc3b
--- /dev/null
+++ b/src/test/ui/parser/expr-as-stmt-2.rs
@@ -0,0 +1,10 @@
+// This is not autofixable because we give extra suggestions to end the first expression with `;`.
+fn foo(a: Option<u32>, b: Option<u32>) -> bool {
+ if let Some(x) = a { true } else { false }
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+ && //~ ERROR mismatched types
+ if let Some(y) = a { true } else { false }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr
new file mode 100644
index 000000000..9b939f05e
--- /dev/null
+++ b/src/test/ui/parser/expr-as-stmt-2.stderr
@@ -0,0 +1,51 @@
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt-2.rs:3:26
+ |
+LL | if let Some(x) = a { true } else { false }
+ | ---------------------^^^^-----------------
+ | | |
+ | | expected `()`, found `bool`
+ | expected this to be `()`
+ |
+help: you might have meant to return this value
+ |
+LL | if let Some(x) = a { return true; } else { false }
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt-2.rs:3:40
+ |
+LL | if let Some(x) = a { true } else { false }
+ | -----------------------------------^^^^^--
+ | | |
+ | | expected `()`, found `bool`
+ | expected this to be `()`
+ |
+help: you might have meant to return this value
+ |
+LL | if let Some(x) = a { true } else { return false; }
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt-2.rs:6:5
+ |
+LL | fn foo(a: Option<u32>, b: Option<u32>) -> bool {
+ | ---- expected `bool` because of return type
+...
+LL | / &&
+LL | | if let Some(y) = a { true } else { false }
+ | |______________________________________________^ expected `bool`, found `&&bool`
+ |
+help: consider removing the `&&`
+ |
+LL - &&
+LL + if let Some(y) = a { true } else { false }
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | (if let Some(x) = a { true } else { false })
+ | + +
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed
new file mode 100644
index 000000000..36709eea1
--- /dev/null
+++ b/src/test/ui/parser/expr-as-stmt.fixed
@@ -0,0 +1,67 @@
+// run-rustfix
+// rustfix-only-machine-applicable
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(unused_must_use)]
+
+fn foo() -> i32 {
+ ({2}) + {2} //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+}
+
+fn bar() -> i32 {
+ ({2}) + 2 //~ ERROR leading `+` is not supported
+ //~^ ERROR mismatched types
+}
+
+fn zul() -> u32 {
+ let foo = 3;
+ ({ 42 }) + foo; //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+ 32
+}
+
+fn baz() -> i32 {
+ ({ 3 }) * 3 //~ ERROR type `{integer}` cannot be dereferenced
+ //~^ ERROR mismatched types
+}
+
+fn moo(x: u32) -> bool {
+ (match x {
+ _ => 1,
+ }) > 0 //~ ERROR expected expression
+}
+
+fn qux() -> u32 {
+ ({2}) - 2 //~ ERROR cannot apply unary operator `-` to type `u32`
+ //~^ ERROR mismatched types
+}
+
+fn space_cadet() -> bool {
+ ({ true }) | { true } //~ ERROR E0308
+ //~^ ERROR expected parameter name
+}
+
+fn revenge_from_mars() -> bool {
+ ({ true }) && { true } //~ ERROR E0308
+ //~^ ERROR mismatched types
+}
+
+fn attack_from_mars() -> bool {
+ ({ true }) || { true } //~ ERROR E0308
+ //~^ ERROR mismatched types
+}
+
+// This gets corrected by adding a semicolon, instead of parens.
+// It's placed here to help keep track of the way this diagnostic
+// needs to interact with type checking to avoid MachineApplicable
+// suggestions that actually break stuff.
+//
+// If you're wondering what happens if that `foo()` is a `true` like
+// all the ones above use? Nothing. It makes neither suggestion in
+// that case.
+fn asteroids() -> impl FnOnce() -> bool {
+ { foo(); } || { true } //~ ERROR E0308
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs
new file mode 100644
index 000000000..92bb972b2
--- /dev/null
+++ b/src/test/ui/parser/expr-as-stmt.rs
@@ -0,0 +1,67 @@
+// run-rustfix
+// rustfix-only-machine-applicable
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(unused_must_use)]
+
+fn foo() -> i32 {
+ {2} + {2} //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+}
+
+fn bar() -> i32 {
+ {2} + 2 //~ ERROR leading `+` is not supported
+ //~^ ERROR mismatched types
+}
+
+fn zul() -> u32 {
+ let foo = 3;
+ { 42 } + foo; //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+ 32
+}
+
+fn baz() -> i32 {
+ { 3 } * 3 //~ ERROR type `{integer}` cannot be dereferenced
+ //~^ ERROR mismatched types
+}
+
+fn moo(x: u32) -> bool {
+ match x {
+ _ => 1,
+ } > 0 //~ ERROR expected expression
+}
+
+fn qux() -> u32 {
+ {2} - 2 //~ ERROR cannot apply unary operator `-` to type `u32`
+ //~^ ERROR mismatched types
+}
+
+fn space_cadet() -> bool {
+ { true } | { true } //~ ERROR E0308
+ //~^ ERROR expected parameter name
+}
+
+fn revenge_from_mars() -> bool {
+ { true } && { true } //~ ERROR E0308
+ //~^ ERROR mismatched types
+}
+
+fn attack_from_mars() -> bool {
+ { true } || { true } //~ ERROR E0308
+ //~^ ERROR mismatched types
+}
+
+// This gets corrected by adding a semicolon, instead of parens.
+// It's placed here to help keep track of the way this diagnostic
+// needs to interact with type checking to avoid MachineApplicable
+// suggestions that actually break stuff.
+//
+// If you're wondering what happens if that `foo()` is a `true` like
+// all the ones above use? Nothing. It makes neither suggestion in
+// that case.
+fn asteroids() -> impl FnOnce() -> bool {
+ { foo() } || { true } //~ ERROR E0308
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
new file mode 100644
index 000000000..858b4e8db
--- /dev/null
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -0,0 +1,216 @@
+error: expected expression, found `+`
+ --> $DIR/expr-as-stmt.rs:8:9
+ |
+LL | {2} + {2}
+ | ^ expected expression
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({2}) + {2}
+ | + +
+
+error: leading `+` is not supported
+ --> $DIR/expr-as-stmt.rs:13:9
+ |
+LL | {2} + 2
+ | ^ unexpected `+`
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({2}) + 2
+ | + +
+
+error: expected expression, found `+`
+ --> $DIR/expr-as-stmt.rs:19:12
+ |
+LL | { 42 } + foo;
+ | ^ expected expression
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({ 42 }) + foo;
+ | + +
+
+error: expected expression, found `>`
+ --> $DIR/expr-as-stmt.rs:32:7
+ |
+LL | } > 0
+ | ^ expected expression
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL ~ (match x {
+LL | _ => 1,
+LL ~ }) > 0
+ |
+
+error: expected parameter name, found `{`
+ --> $DIR/expr-as-stmt.rs:41:16
+ |
+LL | { true } | { true }
+ | ^ expected parameter name
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({ true }) | { true }
+ | + +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:64:7
+ |
+LL | { foo() } || { true }
+ | ^^^^^- help: consider using a semicolon here: `;`
+ | |
+ | expected `()`, found `i32`
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:8:6
+ |
+LL | {2} + {2}
+ | ^ expected `()`, found integer
+ |
+help: you might have meant to return this value
+ |
+LL | {return 2;} + {2}
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:13:6
+ |
+LL | {2} + 2
+ | ^ expected `()`, found integer
+ |
+help: you might have meant to return this value
+ |
+LL | {return 2;} + 2
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:19:7
+ |
+LL | { 42 } + foo;
+ | ^^ expected `()`, found integer
+ |
+help: you might have meant to return this value
+ |
+LL | { return 42; } + foo;
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:25:7
+ |
+LL | { 3 } * 3
+ | ^ expected `()`, found integer
+ |
+help: you might have meant to return this value
+ |
+LL | { return 3; } * 3
+ | ++++++ +
+
+error[E0614]: type `{integer}` cannot be dereferenced
+ --> $DIR/expr-as-stmt.rs:25:11
+ |
+LL | { 3 } * 3
+ | ^^^
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({ 3 }) * 3
+ | + +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:36:6
+ |
+LL | {2} - 2
+ | ^ expected `()`, found integer
+ |
+help: you might have meant to return this value
+ |
+LL | {return 2;} - 2
+ | ++++++ +
+
+error[E0600]: cannot apply unary operator `-` to type `u32`
+ --> $DIR/expr-as-stmt.rs:36:9
+ |
+LL | {2} - 2
+ | ^^^ cannot apply unary operator `-`
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({2}) - 2
+ | + +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:41:7
+ |
+LL | { true } | { true }
+ | ^^^^ expected `()`, found `bool`
+ |
+help: you might have meant to return this value
+ |
+LL | { return true; } | { true }
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:46:7
+ |
+LL | { true } && { true }
+ | ^^^^ expected `()`, found `bool`
+ |
+help: you might have meant to return this value
+ |
+LL | { return true; } && { true }
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:46:14
+ |
+LL | fn revenge_from_mars() -> bool {
+ | ---- expected `bool` because of return type
+LL | { true } && { true }
+ | ^^^^^^^^^^^ expected `bool`, found `&&bool`
+ |
+help: consider removing the `&&`
+ |
+LL - { true } && { true }
+LL + { true } { true }
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | ({ true }) && { true }
+ | + +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:51:7
+ |
+LL | { true } || { true }
+ | ^^^^ expected `()`, found `bool`
+ |
+help: you might have meant to return this value
+ |
+LL | { return true; } || { true }
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:51:14
+ |
+LL | fn attack_from_mars() -> bool {
+ | ---- expected `bool` because of return type
+LL | { true } || { true }
+ | ^^^^^^^^^^^ expected `bool`, found closure
+ |
+ = note: expected type `bool`
+ found closure `[closure@$DIR/expr-as-stmt.rs:51:14: 51:16]`
+help: use parentheses to call this closure
+ |
+LL | { true } (|| { true })()
+ | + +++
+help: parentheses are required to parse this as an expression
+ |
+LL | ({ true }) || { true }
+ | + +
+
+error: aborting due to 18 previous errors
+
+Some errors have detailed explanations: E0308, E0600, E0614.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
new file mode 100644
index 000000000..8f5d7f4f7
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
@@ -0,0 +1,47 @@
+#![allow(clashing_extern_declarations)]
+// check-pass
+
+// In this test we check that the parser accepts an ABI string when it
+// comes from a macro `literal` or `expr` fragment as opposed to a hardcoded string.
+
+fn main() {}
+
+macro_rules! abi_from_lit_frag {
+ ($abi:literal) => {
+ extern $abi {
+ fn _import();
+ }
+
+ extern $abi fn _export() {}
+
+ type _PTR = extern $abi fn();
+ }
+}
+
+macro_rules! abi_from_expr_frag {
+ ($abi:expr) => {
+ extern $abi {
+ fn _import();
+ }
+
+ extern $abi fn _export() {}
+
+ type _PTR = extern $abi fn();
+ };
+}
+
+mod rust {
+ abi_from_lit_frag!("Rust");
+}
+
+mod c {
+ abi_from_lit_frag!("C");
+}
+
+mod rust_expr {
+ abi_from_expr_frag!("Rust");
+}
+
+mod c_expr {
+ abi_from_expr_frag!("C");
+}
diff --git a/src/test/ui/parser/extern-abi-raw-strings.rs b/src/test/ui/parser/extern-abi-raw-strings.rs
new file mode 100644
index 000000000..fad855a21
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-raw-strings.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// Check that the string literal in `extern lit` will accept raw strings.
+
+fn main() {}
+
+extern r#"C"# fn foo() {}
+
+extern r#"C"# {
+ fn bar();
+}
+
+type T = extern r#"C"# fn();
diff --git a/src/test/ui/parser/extern-abi-string-escaping.rs b/src/test/ui/parser/extern-abi-string-escaping.rs
new file mode 100644
index 000000000..87bd31aab
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-string-escaping.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// Check that the string literal in `extern lit` will escapes.
+
+fn main() {}
+
+extern "\x43" fn foo() {}
+
+extern "\x43" {
+ fn bar();
+}
+
+type T = extern "\x43" fn();
diff --git a/src/test/ui/parser/extern-abi-syntactic.rs b/src/test/ui/parser/extern-abi-syntactic.rs
new file mode 100644
index 000000000..7d2bbfe8a
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-syntactic.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// Check that from the grammar's point of view,
+// the specific set of ABIs is not part of it.
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn foo() {}
+
+#[cfg(FALSE)]
+extern "some_abi_that_we_are_sure_does_not_exist_semantically" {
+ fn foo();
+}
+
+#[cfg(FALSE)]
+type T = extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn();
diff --git a/src/test/ui/parser/extern-crate-async.rs b/src/test/ui/parser/extern-crate-async.rs
new file mode 100644
index 000000000..6a54ac7f4
--- /dev/null
+++ b/src/test/ui/parser/extern-crate-async.rs
@@ -0,0 +1,12 @@
+// Make sure that we don't parse `extern crate async`
+// the front matter of a function leading us astray.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern crate async;
+
+#[cfg(FALSE)]
+extern crate async as something_else;
diff --git a/src/test/ui/parser/extern-crate-unexpected-token.rs b/src/test/ui/parser/extern-crate-unexpected-token.rs
new file mode 100644
index 000000000..7687f5e64
--- /dev/null
+++ b/src/test/ui/parser/extern-crate-unexpected-token.rs
@@ -0,0 +1 @@
+extern crte foo; //~ ERROR expected one of `crate` or `{`, found `crte`
diff --git a/src/test/ui/parser/extern-crate-unexpected-token.stderr b/src/test/ui/parser/extern-crate-unexpected-token.stderr
new file mode 100644
index 000000000..e9d287ac0
--- /dev/null
+++ b/src/test/ui/parser/extern-crate-unexpected-token.stderr
@@ -0,0 +1,8 @@
+error: expected one of `crate` or `{`, found `crte`
+ --> $DIR/extern-crate-unexpected-token.rs:1:8
+ |
+LL | extern crte foo;
+ | ^^^^ expected one of `crate` or `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/extern-expected-fn-or-brace.rs b/src/test/ui/parser/extern-expected-fn-or-brace.rs
new file mode 100644
index 000000000..1dcea1744
--- /dev/null
+++ b/src/test/ui/parser/extern-expected-fn-or-brace.rs
@@ -0,0 +1,3 @@
+// Verifies that the expected token errors for `extern crate` are raised.
+
+extern "C" mod foo; //~ERROR expected `{`, found keyword `mod`
diff --git a/src/test/ui/parser/extern-expected-fn-or-brace.stderr b/src/test/ui/parser/extern-expected-fn-or-brace.stderr
new file mode 100644
index 000000000..258a2c268
--- /dev/null
+++ b/src/test/ui/parser/extern-expected-fn-or-brace.stderr
@@ -0,0 +1,8 @@
+error: expected `{`, found keyword `mod`
+ --> $DIR/extern-expected-fn-or-brace.rs:3:12
+ |
+LL | extern "C" mod foo;
+ | ^^^ expected `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/extern-foreign-crate.rs b/src/test/ui/parser/extern-foreign-crate.rs
new file mode 100644
index 000000000..a5da77dc7
--- /dev/null
+++ b/src/test/ui/parser/extern-foreign-crate.rs
@@ -0,0 +1,4 @@
+// Verifies that the expected token errors for `extern crate` are
+// raised
+
+extern crate foo {} //~ERROR expected one of `;` or `as`, found `{`
diff --git a/src/test/ui/parser/extern-foreign-crate.stderr b/src/test/ui/parser/extern-foreign-crate.stderr
new file mode 100644
index 000000000..eb75c0fc9
--- /dev/null
+++ b/src/test/ui/parser/extern-foreign-crate.stderr
@@ -0,0 +1,8 @@
+error: expected one of `;` or `as`, found `{`
+ --> $DIR/extern-foreign-crate.rs:4:18
+ |
+LL | extern crate foo {}
+ | ^ expected one of `;` or `as`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/extern-no-fn.rs b/src/test/ui/parser/extern-no-fn.rs
new file mode 100644
index 000000000..73568609c
--- /dev/null
+++ b/src/test/ui/parser/extern-no-fn.rs
@@ -0,0 +1,6 @@
+extern "C" {
+ f(); //~ ERROR expected one of `!` or `::`, found `(`
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/extern-no-fn.stderr b/src/test/ui/parser/extern-no-fn.stderr
new file mode 100644
index 000000000..d9183d564
--- /dev/null
+++ b/src/test/ui/parser/extern-no-fn.stderr
@@ -0,0 +1,12 @@
+error: expected one of `!` or `::`, found `(`
+ --> $DIR/extern-no-fn.rs:2:6
+ |
+LL | extern "C" {
+ | - while parsing this item list starting here
+LL | f();
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/float-field-interpolated.rs b/src/test/ui/parser/float-field-interpolated.rs
new file mode 100644
index 000000000..a30532035
--- /dev/null
+++ b/src/test/ui/parser/float-field-interpolated.rs
@@ -0,0 +1,17 @@
+struct S(u8, (u8, u8));
+
+macro_rules! generate_field_accesses {
+ ($a:tt, $b:literal, $c:expr) => {
+ let s = S(0, (0, 0));
+
+ s.$a; // OK
+ { s.$b; } //~ ERROR unexpected token: `1.1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1`
+ { s.$c; } //~ ERROR unexpected token: `1.1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1`
+ };
+}
+
+fn main() {
+ generate_field_accesses!(1.1, 1.1, 1.1);
+}
diff --git a/src/test/ui/parser/float-field-interpolated.stderr b/src/test/ui/parser/float-field-interpolated.stderr
new file mode 100644
index 000000000..664adb358
--- /dev/null
+++ b/src/test/ui/parser/float-field-interpolated.stderr
@@ -0,0 +1,46 @@
+error: unexpected token: `1.1`
+ --> $DIR/float-field-interpolated.rs:8:13
+ |
+LL | { s.$b; }
+ | ^^
+...
+LL | generate_field_accesses!(1.1, 1.1, 1.1);
+ | --------------------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1`
+ --> $DIR/float-field-interpolated.rs:8:13
+ |
+LL | { s.$b; }
+ | ^^ expected one of `.`, `;`, `?`, `}`, or an operator
+...
+LL | generate_field_accesses!(1.1, 1.1, 1.1);
+ | --------------------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: unexpected token: `1.1`
+ --> $DIR/float-field-interpolated.rs:10:13
+ |
+LL | { s.$c; }
+ | ^^
+...
+LL | generate_field_accesses!(1.1, 1.1, 1.1);
+ | --------------------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1`
+ --> $DIR/float-field-interpolated.rs:10:13
+ |
+LL | { s.$c; }
+ | ^^ expected one of `.`, `;`, `?`, `}`, or an operator
+...
+LL | generate_field_accesses!(1.1, 1.1, 1.1);
+ | --------------------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `generate_field_accesses` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/float-field.rs b/src/test/ui/parser/float-field.rs
new file mode 100644
index 000000000..eaa7465dc
--- /dev/null
+++ b/src/test/ui/parser/float-field.rs
@@ -0,0 +1,62 @@
+struct S(u8, (u8, u8));
+
+fn main() {
+ let s = S(0, (0, 0));
+
+ s.1e1; //~ ERROR no field `1e1` on type `S`
+ s.1.; //~ ERROR unexpected token: `;`
+ s.1.1;
+ s.1.1e1; //~ ERROR no field `1e1` on type `(u8, u8)`
+ { s.1e+; } //~ ERROR unexpected token: `1e+`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+`
+ //~| ERROR expected at least one digit in exponent
+ { s.1e-; } //~ ERROR unexpected token: `1e-`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-`
+ //~| ERROR expected at least one digit in exponent
+ { s.1e+1; } //~ ERROR unexpected token: `1e+1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1`
+ { s.1e-1; } //~ ERROR unexpected token: `1e-1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1`
+ { s.1.1e+1; } //~ ERROR unexpected token: `1.1e+1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1`
+ { s.1.1e-1; } //~ ERROR unexpected token: `1.1e-1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1`
+ s.0x1e1; //~ ERROR no field `0x1e1` on type `S`
+ s.0x1.; //~ ERROR no field `0x1` on type `S`
+ //~| ERROR hexadecimal float literal is not supported
+ //~| ERROR unexpected token: `;`
+ s.0x1.1; //~ ERROR no field `0x1` on type `S`
+ //~| ERROR hexadecimal float literal is not supported
+ s.0x1.1e1; //~ ERROR no field `0x1` on type `S`
+ //~| ERROR hexadecimal float literal is not supported
+ { s.0x1e+; } //~ ERROR expected expression, found `;`
+ { s.0x1e-; } //~ ERROR expected expression, found `;`
+ s.0x1e+1; //~ ERROR no field `0x1e` on type `S`
+ s.0x1e-1; //~ ERROR no field `0x1e` on type `S`
+ { s.0x1.1e+1; } //~ ERROR unexpected token: `0x1.1e+1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1`
+ //~| ERROR hexadecimal float literal is not supported
+ { s.0x1.1e-1; } //~ ERROR unexpected token: `0x1.1e-1`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1`
+ //~| ERROR hexadecimal float literal is not supported
+ s.1e1f32; //~ ERROR no field `1e1` on type `S`
+ //~| ERROR suffixes on a tuple index are invalid
+ s.1.f32; //~ ERROR no field `f32` on type `(u8, u8)`
+ s.1.1f32; //~ ERROR suffixes on a tuple index are invalid
+ s.1.1e1f32; //~ ERROR no field `1e1` on type `(u8, u8)`
+ //~| ERROR suffixes on a tuple index are invalid
+ { s.1e+f32; } //~ ERROR unexpected token: `1e+f32`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32`
+ //~| ERROR expected at least one digit in exponent
+ { s.1e-f32; } //~ ERROR unexpected token: `1e-f32`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32`
+ //~| ERROR expected at least one digit in exponent
+ { s.1e+1f32; } //~ ERROR unexpected token: `1e+1f32`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32`
+ { s.1e-1f32; } //~ ERROR unexpected token: `1e-1f32`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32`
+ { s.1.1e+1f32; } //~ ERROR unexpected token: `1.1e+1f32`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32`
+ { s.1.1e-1f32; } //~ ERROR unexpected token: `1.1e-1f32`
+ //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32`
+}
diff --git a/src/test/ui/parser/float-field.stderr b/src/test/ui/parser/float-field.stderr
new file mode 100644
index 000000000..7090efc50
--- /dev/null
+++ b/src/test/ui/parser/float-field.stderr
@@ -0,0 +1,349 @@
+error: expected at least one digit in exponent
+ --> $DIR/float-field.rs:10:9
+ |
+LL | { s.1e+; }
+ | ^^^
+
+error: expected at least one digit in exponent
+ --> $DIR/float-field.rs:13:9
+ |
+LL | { s.1e-; }
+ | ^^^
+
+error: hexadecimal float literal is not supported
+ --> $DIR/float-field.rs:25:7
+ |
+LL | s.0x1.;
+ | ^^^^
+
+error: hexadecimal float literal is not supported
+ --> $DIR/float-field.rs:28:7
+ |
+LL | s.0x1.1;
+ | ^^^^^
+
+error: hexadecimal float literal is not supported
+ --> $DIR/float-field.rs:30:7
+ |
+LL | s.0x1.1e1;
+ | ^^^^^^^
+
+error: hexadecimal float literal is not supported
+ --> $DIR/float-field.rs:36:9
+ |
+LL | { s.0x1.1e+1; }
+ | ^^^^^^^^
+
+error: hexadecimal float literal is not supported
+ --> $DIR/float-field.rs:39:9
+ |
+LL | { s.0x1.1e-1; }
+ | ^^^^^^^^
+
+error: expected at least one digit in exponent
+ --> $DIR/float-field.rs:48:9
+ |
+LL | { s.1e+f32; }
+ | ^^^^^^
+
+error: expected at least one digit in exponent
+ --> $DIR/float-field.rs:51:9
+ |
+LL | { s.1e-f32; }
+ | ^^^^^^
+
+error: unexpected token: `;`
+ --> $DIR/float-field.rs:7:9
+ |
+LL | s.1.;
+ | ^
+
+error: unexpected token: `1e+`
+ --> $DIR/float-field.rs:10:9
+ |
+LL | { s.1e+; }
+ | ^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+`
+ --> $DIR/float-field.rs:10:9
+ |
+LL | { s.1e+; }
+ | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1e-`
+ --> $DIR/float-field.rs:13:9
+ |
+LL | { s.1e-; }
+ | ^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-`
+ --> $DIR/float-field.rs:13:9
+ |
+LL | { s.1e-; }
+ | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1e+1`
+ --> $DIR/float-field.rs:16:9
+ |
+LL | { s.1e+1; }
+ | ^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1`
+ --> $DIR/float-field.rs:16:9
+ |
+LL | { s.1e+1; }
+ | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1e-1`
+ --> $DIR/float-field.rs:18:9
+ |
+LL | { s.1e-1; }
+ | ^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1`
+ --> $DIR/float-field.rs:18:9
+ |
+LL | { s.1e-1; }
+ | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1.1e+1`
+ --> $DIR/float-field.rs:20:9
+ |
+LL | { s.1.1e+1; }
+ | ^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1`
+ --> $DIR/float-field.rs:20:9
+ |
+LL | { s.1.1e+1; }
+ | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1.1e-1`
+ --> $DIR/float-field.rs:22:9
+ |
+LL | { s.1.1e-1; }
+ | ^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1`
+ --> $DIR/float-field.rs:22:9
+ |
+LL | { s.1.1e-1; }
+ | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `;`
+ --> $DIR/float-field.rs:25:11
+ |
+LL | s.0x1.;
+ | ^
+
+error: expected expression, found `;`
+ --> $DIR/float-field.rs:32:14
+ |
+LL | { s.0x1e+; }
+ | ^ expected expression
+
+error: expected expression, found `;`
+ --> $DIR/float-field.rs:33:14
+ |
+LL | { s.0x1e-; }
+ | ^ expected expression
+
+error: unexpected token: `0x1.1e+1`
+ --> $DIR/float-field.rs:36:9
+ |
+LL | { s.0x1.1e+1; }
+ | ^^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1`
+ --> $DIR/float-field.rs:36:9
+ |
+LL | { s.0x1.1e+1; }
+ | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `0x1.1e-1`
+ --> $DIR/float-field.rs:39:9
+ |
+LL | { s.0x1.1e-1; }
+ | ^^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1`
+ --> $DIR/float-field.rs:39:9
+ |
+LL | { s.0x1.1e-1; }
+ | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: suffixes on a tuple index are invalid
+ --> $DIR/float-field.rs:42:7
+ |
+LL | s.1e1f32;
+ | ^^^^^^ invalid suffix `f32`
+
+error: suffixes on a tuple index are invalid
+ --> $DIR/float-field.rs:45:7
+ |
+LL | s.1.1f32;
+ | ^^^^^^ invalid suffix `f32`
+
+error: suffixes on a tuple index are invalid
+ --> $DIR/float-field.rs:46:7
+ |
+LL | s.1.1e1f32;
+ | ^^^^^^^^ invalid suffix `f32`
+
+error: unexpected token: `1e+f32`
+ --> $DIR/float-field.rs:48:9
+ |
+LL | { s.1e+f32; }
+ | ^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32`
+ --> $DIR/float-field.rs:48:9
+ |
+LL | { s.1e+f32; }
+ | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1e-f32`
+ --> $DIR/float-field.rs:51:9
+ |
+LL | { s.1e-f32; }
+ | ^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32`
+ --> $DIR/float-field.rs:51:9
+ |
+LL | { s.1e-f32; }
+ | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1e+1f32`
+ --> $DIR/float-field.rs:54:9
+ |
+LL | { s.1e+1f32; }
+ | ^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32`
+ --> $DIR/float-field.rs:54:9
+ |
+LL | { s.1e+1f32; }
+ | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1e-1f32`
+ --> $DIR/float-field.rs:56:9
+ |
+LL | { s.1e-1f32; }
+ | ^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32`
+ --> $DIR/float-field.rs:56:9
+ |
+LL | { s.1e-1f32; }
+ | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1.1e+1f32`
+ --> $DIR/float-field.rs:58:9
+ |
+LL | { s.1.1e+1f32; }
+ | ^^^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32`
+ --> $DIR/float-field.rs:58:9
+ |
+LL | { s.1.1e+1f32; }
+ | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: unexpected token: `1.1e-1f32`
+ --> $DIR/float-field.rs:60:9
+ |
+LL | { s.1.1e-1f32; }
+ | ^^^^^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32`
+ --> $DIR/float-field.rs:60:9
+ |
+LL | { s.1.1e-1f32; }
+ | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error[E0609]: no field `1e1` on type `S`
+ --> $DIR/float-field.rs:6:7
+ |
+LL | s.1e1;
+ | ^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `1e1` on type `(u8, u8)`
+ --> $DIR/float-field.rs:9:9
+ |
+LL | s.1.1e1;
+ | ^^^
+
+error[E0609]: no field `0x1e1` on type `S`
+ --> $DIR/float-field.rs:24:7
+ |
+LL | s.0x1e1;
+ | ^^^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `0x1` on type `S`
+ --> $DIR/float-field.rs:25:7
+ |
+LL | s.0x1.;
+ | ^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `0x1` on type `S`
+ --> $DIR/float-field.rs:28:7
+ |
+LL | s.0x1.1;
+ | ^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `0x1` on type `S`
+ --> $DIR/float-field.rs:30:7
+ |
+LL | s.0x1.1e1;
+ | ^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `0x1e` on type `S`
+ --> $DIR/float-field.rs:34:7
+ |
+LL | s.0x1e+1;
+ | ^^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `0x1e` on type `S`
+ --> $DIR/float-field.rs:35:7
+ |
+LL | s.0x1e-1;
+ | ^^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `1e1` on type `S`
+ --> $DIR/float-field.rs:42:7
+ |
+LL | s.1e1f32;
+ | ^^^^^^ unknown field
+ |
+ = note: available fields are: `0`, `1`
+
+error[E0609]: no field `f32` on type `(u8, u8)`
+ --> $DIR/float-field.rs:44:9
+ |
+LL | s.1.f32;
+ | ^^^
+
+error[E0609]: no field `1e1` on type `(u8, u8)`
+ --> $DIR/float-field.rs:46:7
+ |
+LL | s.1.1e1f32;
+ | ^^^^^^^^
+
+error: aborting due to 55 previous errors
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/parser/float-literals.rs b/src/test/ui/parser/float-literals.rs
new file mode 100644
index 000000000..1e9319fd2
--- /dev/null
+++ b/src/test/ui/parser/float-literals.rs
@@ -0,0 +1,9 @@
+// build-pass
+// ignore-tidy-linelength
+// Regression test for #31109 and #31407.
+
+pub fn main() {
+ let _: f64 = 0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333;
+
+ let _: f64 = 1234567890123456789012345678901234567890e-340;
+}
diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs
new file mode 100644
index 000000000..21d753ad0
--- /dev/null
+++ b/src/test/ui/parser/fn-arg-doc-comment.rs
@@ -0,0 +1,30 @@
+pub fn f( //~ NOTE function defined here
+ /// Comment
+ //~^ ERROR documentation comments cannot be applied to function parameters
+ //~| NOTE doc comments are not allowed here
+ //~| NOTE
+ id: u8,
+ /// Other
+ //~^ ERROR documentation comments cannot be applied to function parameters
+ //~| NOTE doc comments are not allowed here
+ //~| NOTE
+ a: u8,
+) {}
+
+fn bar(id: #[allow(dead_code)] i32) {}
+//~^ ERROR attributes cannot be applied to a function parameter's type
+//~| NOTE attributes are not allowed here
+//~| NOTE function defined here
+//~| NOTE
+
+fn main() {
+ // verify that the parser recovered and properly typechecked the args
+ f("", "");
+ //~^ ERROR arguments to this function are incorrect
+ //~| NOTE expected `u8`, found `&str`
+ //~| NOTE expected `u8`, found `&str`
+ bar("");
+ //~^ ERROR mismatched types
+ //~| NOTE arguments to this function are incorrect
+ //~| NOTE expected `i32`, found `&str`
+}
diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr
new file mode 100644
index 000000000..c8d7e2efe
--- /dev/null
+++ b/src/test/ui/parser/fn-arg-doc-comment.stderr
@@ -0,0 +1,61 @@
+error: attributes cannot be applied to a function parameter's type
+ --> $DIR/fn-arg-doc-comment.rs:14:12
+ |
+LL | fn bar(id: #[allow(dead_code)] i32) {}
+ | ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/fn-arg-doc-comment.rs:2:5
+ |
+LL | /// Comment
+ | ^^^^^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/fn-arg-doc-comment.rs:7:5
+ |
+LL | /// Other
+ | ^^^^^^^^^ doc comments are not allowed here
+
+error[E0308]: arguments to this function are incorrect
+ --> $DIR/fn-arg-doc-comment.rs:22:5
+ |
+LL | f("", "");
+ | ^ -- -- expected `u8`, found `&str`
+ | |
+ | expected `u8`, found `&str`
+ |
+note: function defined here
+ --> $DIR/fn-arg-doc-comment.rs:1:8
+ |
+LL | pub fn f(
+ | ^
+LL | / /// Comment
+LL | |
+LL | |
+LL | |
+LL | | id: u8,
+ | |__________-
+LL | / /// Other
+LL | |
+LL | |
+LL | |
+LL | | a: u8,
+ | |_________-
+
+error[E0308]: mismatched types
+ --> $DIR/fn-arg-doc-comment.rs:26:9
+ |
+LL | bar("");
+ | --- ^^ expected `i32`, found `&str`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/fn-arg-doc-comment.rs:14:4
+ |
+LL | fn bar(id: #[allow(dead_code)] i32) {}
+ | ^^^ ---------------------------
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/fn-body-eq-expr-semi.rs b/src/test/ui/parser/fn-body-eq-expr-semi.rs
new file mode 100644
index 000000000..7127ba8da
--- /dev/null
+++ b/src/test/ui/parser/fn-body-eq-expr-semi.rs
@@ -0,0 +1,23 @@
+fn main() {}
+
+fn syntax() {
+ fn foo() = 42; //~ ERROR function body cannot be `= expression;`
+ fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;`
+}
+
+extern "C" {
+ fn foo() = 42; //~ ERROR function body cannot be `= expression;`
+ //~^ ERROR incorrect function inside `extern` block
+ fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;`
+ //~^ ERROR incorrect function inside `extern` block
+}
+
+trait Foo {
+ fn foo() = 42; //~ ERROR function body cannot be `= expression;`
+ fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;`
+}
+
+impl Foo for () {
+ fn foo() = 42; //~ ERROR function body cannot be `= expression;`
+ fn bar() -> u8 = 42; //~ ERROR function body cannot be `= expression;`
+}
diff --git a/src/test/ui/parser/fn-body-eq-expr-semi.stderr b/src/test/ui/parser/fn-body-eq-expr-semi.stderr
new file mode 100644
index 000000000..f1255d864
--- /dev/null
+++ b/src/test/ui/parser/fn-body-eq-expr-semi.stderr
@@ -0,0 +1,117 @@
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:4:14
+ |
+LL | fn foo() = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn foo() { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:5:20
+ |
+LL | fn bar() -> u8 = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn bar() -> u8 { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:9:14
+ |
+LL | fn foo() = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn foo() { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:11:20
+ |
+LL | fn bar() -> u8 = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn bar() -> u8 { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:16:14
+ |
+LL | fn foo() = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn foo() { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:17:20
+ |
+LL | fn bar() -> u8 = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn bar() -> u8 { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:21:14
+ |
+LL | fn foo() = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn foo() { 42 }
+ | ~ ~
+
+error: function body cannot be `= expression;`
+ --> $DIR/fn-body-eq-expr-semi.rs:22:20
+ |
+LL | fn bar() -> u8 = 42;
+ | ^^^^^
+ |
+help: surround the expression with `{` and `}` instead of `=` and `;`
+ |
+LL | fn bar() -> u8 { 42 }
+ | ~ ~
+
+error: incorrect function inside `extern` block
+ --> $DIR/fn-body-eq-expr-semi.rs:9:8
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL | fn foo() = 42;
+ | ^^^ ----- help: remove the invalid body: `;`
+ | |
+ | cannot have a body
+ |
+ = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: incorrect function inside `extern` block
+ --> $DIR/fn-body-eq-expr-semi.rs:11:8
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+...
+LL | fn bar() -> u8 = 42;
+ | ^^^ ----- help: remove the invalid body: `;`
+ | |
+ | cannot have a body
+ |
+ = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.rs b/src/test/ui/parser/fn-body-optional-semantic-fail.rs
new file mode 100644
index 000000000..12df48880
--- /dev/null
+++ b/src/test/ui/parser/fn-body-optional-semantic-fail.rs
@@ -0,0 +1,27 @@
+// Tests the different rules for `fn` forms requiring the presence or lack of a body.
+
+fn main() {
+ fn f1(); //~ ERROR free function without a body
+ fn f2() {} // OK.
+
+ trait X {
+ fn f1(); // OK.
+ fn f2() {} // OK.
+ }
+
+ struct Y;
+ impl X for Y {
+ fn f1(); //~ ERROR associated function in `impl` without body
+ fn f2() {} // OK.
+ }
+
+ impl Y {
+ fn f3(); //~ ERROR associated function in `impl` without body
+ fn f4() {} // OK.
+ }
+
+ extern "C" {
+ fn f5(); // OK.
+ fn f6() {} //~ ERROR incorrect function inside `extern` block
+ }
+}
diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.stderr b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr
new file mode 100644
index 000000000..14bcd7c16
--- /dev/null
+++ b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr
@@ -0,0 +1,40 @@
+error: free function without a body
+ --> $DIR/fn-body-optional-semantic-fail.rs:4:5
+ |
+LL | fn f1();
+ | ^^^^^^^-
+ | |
+ | help: provide a definition for the function: `{ <body> }`
+
+error: associated function in `impl` without body
+ --> $DIR/fn-body-optional-semantic-fail.rs:14:9
+ |
+LL | fn f1();
+ | ^^^^^^^-
+ | |
+ | help: provide a definition for the function: `{ <body> }`
+
+error: associated function in `impl` without body
+ --> $DIR/fn-body-optional-semantic-fail.rs:19:9
+ |
+LL | fn f3();
+ | ^^^^^^^-
+ | |
+ | help: provide a definition for the function: `{ <body> }`
+
+error: incorrect function inside `extern` block
+ --> $DIR/fn-body-optional-semantic-fail.rs:25:12
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL | fn f5(); // OK.
+LL | fn f6() {}
+ | ^^ -- help: remove the invalid body: `;`
+ | |
+ | cannot have a body
+ |
+ = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/fn-body-optional-syntactic-pass.rs b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs
new file mode 100644
index 000000000..f9dbebf0b
--- /dev/null
+++ b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs
@@ -0,0 +1,31 @@
+// Ensures that all `fn` forms having or lacking a body are syntactically valid.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+ fn f();
+ fn f() {}
+
+ trait X {
+ fn f();
+ fn f() {}
+ }
+
+ impl X for Y {
+ fn f();
+ fn f() {}
+ }
+
+ impl Y {
+ fn f();
+ fn f() {}
+ }
+
+ extern "C" {
+ fn f();
+ fn f();
+ }
+}
diff --git a/src/test/ui/parser/fn-colon-return-type.rs b/src/test/ui/parser/fn-colon-return-type.rs
new file mode 100644
index 000000000..0001ef57c
--- /dev/null
+++ b/src/test/ui/parser/fn-colon-return-type.rs
@@ -0,0 +1,6 @@
+fn foo(x: i32): i32 {
+//~^ ERROR return types are denoted using `->`
+ x
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-colon-return-type.stderr b/src/test/ui/parser/fn-colon-return-type.stderr
new file mode 100644
index 000000000..1de918782
--- /dev/null
+++ b/src/test/ui/parser/fn-colon-return-type.stderr
@@ -0,0 +1,8 @@
+error: return types are denoted using `->`
+ --> $DIR/fn-colon-return-type.rs:1:15
+ |
+LL | fn foo(x: i32): i32 {
+ | ^ help: use `->` instead
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.rs b/src/test/ui/parser/fn-field-parse-error-ice.rs
new file mode 100644
index 000000000..4ea55062f
--- /dev/null
+++ b/src/test/ui/parser/fn-field-parse-error-ice.rs
@@ -0,0 +1,10 @@
+// Regression test for #85794
+
+struct Baz {
+ inner : dyn fn ()
+ //~^ ERROR expected `,`, or `}`, found keyword `fn`
+ //~| ERROR functions are not allowed in struct definitions
+ //~| ERROR cannot find type `dyn` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.stderr b/src/test/ui/parser/fn-field-parse-error-ice.stderr
new file mode 100644
index 000000000..d582f61cc
--- /dev/null
+++ b/src/test/ui/parser/fn-field-parse-error-ice.stderr
@@ -0,0 +1,24 @@
+error: expected `,`, or `}`, found keyword `fn`
+ --> $DIR/fn-field-parse-error-ice.rs:4:16
+ |
+LL | inner : dyn fn ()
+ | ^ help: try adding a comma: `,`
+
+error: functions are not allowed in struct definitions
+ --> $DIR/fn-field-parse-error-ice.rs:4:17
+ |
+LL | inner : dyn fn ()
+ | ^^
+ |
+ = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
+ = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+
+error[E0412]: cannot find type `dyn` in this scope
+ --> $DIR/fn-field-parse-error-ice.rs:4:13
+ |
+LL | inner : dyn fn ()
+ | ^^^ not found in this scope
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs
new file mode 100644
index 000000000..8ff14fb1f
--- /dev/null
+++ b/src/test/ui/parser/fn-header-semantic-fail.rs
@@ -0,0 +1,60 @@
+// Ensures that all `fn` forms can have all the function qualifiers syntactically.
+
+// edition:2018
+
+#![feature(const_extern_fn)]
+
+fn main() {
+ async fn ff1() {} // OK.
+ unsafe fn ff2() {} // OK.
+ const fn ff3() {} // OK.
+ extern "C" fn ff4() {} // OK.
+ const async unsafe extern "C" fn ff5() {}
+ //~^ ERROR functions cannot be both `const` and `async`
+ //~| ERROR cycle detected
+
+ trait X {
+ async fn ft1(); //~ ERROR functions in traits cannot be declared `async`
+ unsafe fn ft2(); // OK.
+ const fn ft3(); //~ ERROR functions in traits cannot be declared const
+ extern "C" fn ft4(); // OK.
+ const async unsafe extern "C" fn ft5();
+ //~^ ERROR functions in traits cannot be declared `async`
+ //~| ERROR functions in traits cannot be declared const
+ //~| ERROR functions cannot be both `const` and `async`
+ }
+
+ struct Y;
+ impl X for Y {
+ async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
+ //~^ ERROR has an incompatible type for trait
+ unsafe fn ft2() {} // OK.
+ const fn ft3() {} //~ ERROR functions in traits cannot be declared const
+ extern "C" fn ft4() {}
+ const async unsafe extern "C" fn ft5() {}
+ //~^ ERROR functions in traits cannot be declared `async`
+ //~| ERROR functions in traits cannot be declared const
+ //~| ERROR functions cannot be both `const` and `async`
+ //~| ERROR cycle detected
+ //~| ERROR has an incompatible type for trait
+ }
+
+ impl Y {
+ async fn fi1() {} // OK.
+ unsafe fn fi2() {} // OK.
+ const fn fi3() {} // OK.
+ extern "C" fn fi4() {} // OK.
+ const async unsafe extern "C" fn fi5() {}
+ //~^ ERROR functions cannot be both `const` and `async`
+ //~| ERROR cycle detected
+ }
+
+ extern "C" {
+ async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+ unsafe fn fe2(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+ const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+ extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+ const async unsafe extern "C" fn fe5(); //~ ERROR functions in `extern` blocks
+ //~^ ERROR functions cannot be both `const` and `async`
+ }
+}
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
new file mode 100644
index 000000000..bc51ba8b8
--- /dev/null
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -0,0 +1,330 @@
+error: functions cannot be both `const` and `async`
+ --> $DIR/fn-header-semantic-fail.rs:12:5
+ |
+LL | const async unsafe extern "C" fn ff5() {}
+ | ^^^^^-^^^^^------------------------------
+ | | |
+ | | `async` because of this
+ | `const` because of this
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:17:9
+ |
+LL | async fn ft1();
+ | -----^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0379]: functions in traits cannot be declared const
+ --> $DIR/fn-header-semantic-fail.rs:19:9
+ |
+LL | const fn ft3();
+ | ^^^^^ functions in traits cannot be const
+
+error[E0379]: functions in traits cannot be declared const
+ --> $DIR/fn-header-semantic-fail.rs:21:9
+ |
+LL | const async unsafe extern "C" fn ft5();
+ | ^^^^^ functions in traits cannot be const
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:21:9
+ |
+LL | const async unsafe extern "C" fn ft5();
+ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error: functions cannot be both `const` and `async`
+ --> $DIR/fn-header-semantic-fail.rs:21:9
+ |
+LL | const async unsafe extern "C" fn ft5();
+ | ^^^^^-^^^^^----------------------------
+ | | |
+ | | `async` because of this
+ | `const` because of this
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:29:9
+ |
+LL | async fn ft1() {}
+ | -----^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0379]: functions in traits cannot be declared const
+ --> $DIR/fn-header-semantic-fail.rs:32:9
+ |
+LL | const fn ft3() {}
+ | ^^^^^ functions in traits cannot be const
+
+error[E0379]: functions in traits cannot be declared const
+ --> $DIR/fn-header-semantic-fail.rs:34:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^ functions in traits cannot be const
+
+error[E0706]: functions in traits cannot be declared `async`
+ --> $DIR/fn-header-semantic-fail.rs:34:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error: functions cannot be both `const` and `async`
+ --> $DIR/fn-header-semantic-fail.rs:34:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^-^^^^^------------------------------
+ | | |
+ | | `async` because of this
+ | `const` because of this
+
+error: functions cannot be both `const` and `async`
+ --> $DIR/fn-header-semantic-fail.rs:47:9
+ |
+LL | const async unsafe extern "C" fn fi5() {}
+ | ^^^^^-^^^^^------------------------------
+ | | |
+ | | `async` because of this
+ | `const` because of this
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/fn-header-semantic-fail.rs:53:18
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+LL | async fn fe1();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn fe1();
+ | ~~
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/fn-header-semantic-fail.rs:54:19
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+LL | async fn fe1();
+LL | unsafe fn fe2();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn fe2();
+ | ~~
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/fn-header-semantic-fail.rs:55:18
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+...
+LL | const fn fe3();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn fe3();
+ | ~~
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/fn-header-semantic-fail.rs:56:23
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+...
+LL | extern "C" fn fe4();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn fe4();
+ | ~~
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/fn-header-semantic-fail.rs:57:42
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+...
+LL | const async unsafe extern "C" fn fe5();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn fe5();
+ | ~~
+
+error: functions cannot be both `const` and `async`
+ --> $DIR/fn-header-semantic-fail.rs:57:9
+ |
+LL | const async unsafe extern "C" fn fe5();
+ | ^^^^^-^^^^^----------------------------
+ | | |
+ | | `async` because of this
+ | `const` because of this
+
+error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}`
+ --> $DIR/fn-header-semantic-fail.rs:12:44
+ |
+LL | const async unsafe extern "C" fn ff5() {}
+ | ^
+ |
+note: ...which requires borrow-checking `main::ff5`...
+ --> $DIR/fn-header-semantic-fail.rs:12:5
+ |
+LL | const async unsafe extern "C" fn ff5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires processing `main::ff5`...
+ --> $DIR/fn-header-semantic-fail.rs:12:5
+ |
+LL | const async unsafe extern "C" fn ff5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const checking `main::ff5`...
+ --> $DIR/fn-header-semantic-fail.rs:12:5
+ |
+LL | const async unsafe extern "C" fn ff5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
+ = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
+ = note: ...which again requires computing type of `main::ff5::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in top-level module
+ --> $DIR/fn-header-semantic-fail.rs:5:1
+ |
+LL | / #![feature(const_extern_fn)]
+LL | |
+LL | | fn main() {
+LL | | async fn ff1() {} // OK.
+... |
+LL | | }
+LL | | }
+ | |_^
+
+error[E0053]: method `ft1` has an incompatible type for trait
+ --> $DIR/fn-header-semantic-fail.rs:29:24
+ |
+LL | async fn ft1() {}
+ | ^
+ | |
+ | checked the `Output` of this `async fn`, found opaque type
+ | expected `()`, found opaque type
+ |
+ = note: while checking the return type of the `async fn`
+note: type in trait
+ --> $DIR/fn-header-semantic-fail.rs:17:23
+ |
+LL | async fn ft1();
+ | ^
+ = note: expected fn pointer `fn()`
+ found fn pointer `fn() -> impl Future<Output = ()>`
+
+error[E0053]: method `ft5` has an incompatible type for trait
+ --> $DIR/fn-header-semantic-fail.rs:34:48
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^
+ | |
+ | checked the `Output` of this `async fn`, found opaque type
+ | expected `()`, found opaque type
+ |
+ = note: while checking the return type of the `async fn`
+note: type in trait
+ --> $DIR/fn-header-semantic-fail.rs:21:47
+ |
+LL | const async unsafe extern "C" fn ft5();
+ | ^
+ = note: expected fn pointer `unsafe extern "C" fn()`
+ found fn pointer `unsafe extern "C" fn() -> impl Future<Output = ()>`
+
+error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`
+ --> $DIR/fn-header-semantic-fail.rs:34:48
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^
+ |
+note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
+ --> $DIR/fn-header-semantic-fail.rs:34:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
+ --> $DIR/fn-header-semantic-fail.rs:34:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
+ --> $DIR/fn-header-semantic-fail.rs:34:9
+ |
+LL | const async unsafe extern "C" fn ft5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
+ = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
+ = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in top-level module
+ --> $DIR/fn-header-semantic-fail.rs:5:1
+ |
+LL | / #![feature(const_extern_fn)]
+LL | |
+LL | | fn main() {
+LL | | async fn ff1() {} // OK.
+... |
+LL | | }
+LL | | }
+ | |_^
+
+error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`
+ --> $DIR/fn-header-semantic-fail.rs:47:48
+ |
+LL | const async unsafe extern "C" fn fi5() {}
+ | ^
+ |
+note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
+ --> $DIR/fn-header-semantic-fail.rs:47:9
+ |
+LL | const async unsafe extern "C" fn fi5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
+ --> $DIR/fn-header-semantic-fail.rs:47:9
+ |
+LL | const async unsafe extern "C" fn fi5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
+ --> $DIR/fn-header-semantic-fail.rs:47:9
+ |
+LL | const async unsafe extern "C" fn fi5() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
+ = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
+ = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in top-level module
+ --> $DIR/fn-header-semantic-fail.rs:5:1
+ |
+LL | / #![feature(const_extern_fn)]
+LL | |
+LL | | fn main() {
+LL | | async fn ff1() {} // OK.
+... |
+LL | | }
+LL | | }
+ | |_^
+
+error: aborting due to 23 previous errors
+
+Some errors have detailed explanations: E0053, E0379, E0391, E0706.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/src/test/ui/parser/fn-header-syntactic-pass.rs b/src/test/ui/parser/fn-header-syntactic-pass.rs
new file mode 100644
index 000000000..68f1f7901
--- /dev/null
+++ b/src/test/ui/parser/fn-header-syntactic-pass.rs
@@ -0,0 +1,47 @@
+// Ensures that all `fn` forms can have all the function qualifiers syntactically.
+
+// check-pass
+// edition:2018
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+ async fn f();
+ unsafe fn f();
+ const fn f();
+ extern "C" fn f();
+ const async unsafe extern "C" fn f();
+
+ trait X {
+ async fn f();
+ unsafe fn f();
+ const fn f();
+ extern "C" fn f();
+ const async unsafe extern "C" fn f();
+ }
+
+ impl X for Y {
+ async fn f();
+ unsafe fn f();
+ const fn f();
+ extern "C" fn f();
+ const async unsafe extern "C" fn f();
+ }
+
+ impl Y {
+ async fn f();
+ unsafe fn f();
+ const fn f();
+ extern "C" fn f();
+ const async unsafe extern "C" fn f();
+ }
+
+ extern "C" {
+ fn f();
+ fn f();
+ fn f();
+ fn f();
+ fn f();
+ }
+}
diff --git a/src/test/ui/parser/fn-returns-fn-pointer.rs b/src/test/ui/parser/fn-returns-fn-pointer.rs
new file mode 100644
index 000000000..15590e324
--- /dev/null
+++ b/src/test/ui/parser/fn-returns-fn-pointer.rs
@@ -0,0 +1,6 @@
+// check-pass
+// Regression test for #78507.
+fn foo() -> Option<fn() -> Option<bool>> {
+ Some(|| Some(true))
+}
+fn main() {}
diff --git a/src/test/ui/parser/foreign-const-semantic-fail.rs b/src/test/ui/parser/foreign-const-semantic-fail.rs
new file mode 100644
index 000000000..c9940b74a
--- /dev/null
+++ b/src/test/ui/parser/foreign-const-semantic-fail.rs
@@ -0,0 +1,9 @@
+fn main() {}
+
+extern "C" {
+ const A: isize;
+ //~^ ERROR extern items cannot be `const`
+ const B: isize = 42;
+ //~^ ERROR extern items cannot be `const`
+ //~| ERROR incorrect `static` inside `extern` block
+}
diff --git a/src/test/ui/parser/foreign-const-semantic-fail.stderr b/src/test/ui/parser/foreign-const-semantic-fail.stderr
new file mode 100644
index 000000000..8dc66c0d0
--- /dev/null
+++ b/src/test/ui/parser/foreign-const-semantic-fail.stderr
@@ -0,0 +1,35 @@
+error: extern items cannot be `const`
+ --> $DIR/foreign-const-semantic-fail.rs:4:11
+ |
+LL | const A: isize;
+ | ------^
+ | |
+ | help: try using a static value: `static`
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: extern items cannot be `const`
+ --> $DIR/foreign-const-semantic-fail.rs:6:11
+ |
+LL | const B: isize = 42;
+ | ------^
+ | |
+ | help: try using a static value: `static`
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: incorrect `static` inside `extern` block
+ --> $DIR/foreign-const-semantic-fail.rs:6:11
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body
+...
+LL | const B: isize = 42;
+ | ^ -- the invalid body
+ | |
+ | cannot have a body
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/foreign-const-syntactic-fail.rs b/src/test/ui/parser/foreign-const-syntactic-fail.rs
new file mode 100644
index 000000000..a6e77f846
--- /dev/null
+++ b/src/test/ui/parser/foreign-const-syntactic-fail.rs
@@ -0,0 +1,9 @@
+// Syntactically, a `const` item inside an `extern { ... }` block is not allowed.
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern "C" {
+ const A: isize; //~ ERROR extern items cannot be `const`
+ const B: isize = 42; //~ ERROR extern items cannot be `const`
+}
diff --git a/src/test/ui/parser/foreign-const-syntactic-fail.stderr b/src/test/ui/parser/foreign-const-syntactic-fail.stderr
new file mode 100644
index 000000000..9cf58fa95
--- /dev/null
+++ b/src/test/ui/parser/foreign-const-syntactic-fail.stderr
@@ -0,0 +1,22 @@
+error: extern items cannot be `const`
+ --> $DIR/foreign-const-syntactic-fail.rs:7:11
+ |
+LL | const A: isize;
+ | ------^
+ | |
+ | help: try using a static value: `static`
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: extern items cannot be `const`
+ --> $DIR/foreign-const-syntactic-fail.rs:8:11
+ |
+LL | const B: isize = 42;
+ | ------^
+ | |
+ | help: try using a static value: `static`
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/foreign-static-semantic-fail.rs b/src/test/ui/parser/foreign-static-semantic-fail.rs
new file mode 100644
index 000000000..3d427ed0e
--- /dev/null
+++ b/src/test/ui/parser/foreign-static-semantic-fail.rs
@@ -0,0 +1,8 @@
+// Syntactically, a foreign static may not have a body.
+
+fn main() {}
+
+extern "C" {
+ static X: u8 = 0; //~ ERROR incorrect `static` inside `extern` block
+ static mut Y: u8 = 0; //~ ERROR incorrect `static` inside `extern` block
+}
diff --git a/src/test/ui/parser/foreign-static-semantic-fail.stderr b/src/test/ui/parser/foreign-static-semantic-fail.stderr
new file mode 100644
index 000000000..105508cfe
--- /dev/null
+++ b/src/test/ui/parser/foreign-static-semantic-fail.stderr
@@ -0,0 +1,27 @@
+error: incorrect `static` inside `extern` block
+ --> $DIR/foreign-static-semantic-fail.rs:6:12
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body
+LL | static X: u8 = 0;
+ | ^ - the invalid body
+ | |
+ | cannot have a body
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: incorrect `static` inside `extern` block
+ --> $DIR/foreign-static-semantic-fail.rs:7:16
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body
+LL | static X: u8 = 0;
+LL | static mut Y: u8 = 0;
+ | ^ - the invalid body
+ | |
+ | cannot have a body
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/foreign-static-syntactic-pass.rs b/src/test/ui/parser/foreign-static-syntactic-pass.rs
new file mode 100644
index 000000000..599496346
--- /dev/null
+++ b/src/test/ui/parser/foreign-static-syntactic-pass.rs
@@ -0,0 +1,11 @@
+// Syntactically, a foreign static may have a body.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern "C" {
+ static X: u8;
+ static mut Y: u8;
+}
diff --git a/src/test/ui/parser/foreign-ty-semantic-fail.rs b/src/test/ui/parser/foreign-ty-semantic-fail.rs
new file mode 100644
index 000000000..96b15232b
--- /dev/null
+++ b/src/test/ui/parser/foreign-ty-semantic-fail.rs
@@ -0,0 +1,18 @@
+#![feature(extern_types)]
+
+fn main() {}
+
+extern "C" {
+ type A: Ord;
+ //~^ ERROR bounds on `type`s in `extern` blocks have no effect
+ type B<'a> where 'a: 'static;
+ //~^ ERROR `type`s inside `extern` blocks cannot have generic parameters
+ //~| ERROR `type`s inside `extern` blocks cannot have `where` clauses
+ type C<T: Ord> where T: 'static;
+ //~^ ERROR `type`s inside `extern` blocks cannot have generic parameters
+ //~| ERROR `type`s inside `extern` blocks cannot have `where` clauses
+ type D = u8;
+ //~^ ERROR incorrect `type` inside `extern` block
+
+ type E: where;
+}
diff --git a/src/test/ui/parser/foreign-ty-semantic-fail.stderr b/src/test/ui/parser/foreign-ty-semantic-fail.stderr
new file mode 100644
index 000000000..588e4966a
--- /dev/null
+++ b/src/test/ui/parser/foreign-ty-semantic-fail.stderr
@@ -0,0 +1,65 @@
+error: bounds on `type`s in `extern` blocks have no effect
+ --> $DIR/foreign-ty-semantic-fail.rs:6:13
+ |
+LL | type A: Ord;
+ | ^^^
+
+error: `type`s inside `extern` blocks cannot have generic parameters
+ --> $DIR/foreign-ty-semantic-fail.rs:8:11
+ |
+LL | extern "C" {
+ | ---------- `extern` block begins here
+...
+LL | type B<'a> where 'a: 'static;
+ | ^^^^ help: remove the generic parameters
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: `type`s inside `extern` blocks cannot have `where` clauses
+ --> $DIR/foreign-ty-semantic-fail.rs:8:16
+ |
+LL | extern "C" {
+ | ---------- `extern` block begins here
+...
+LL | type B<'a> where 'a: 'static;
+ | ^^^^^^^^^^^^^^^^^ help: remove the `where` clause
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: `type`s inside `extern` blocks cannot have generic parameters
+ --> $DIR/foreign-ty-semantic-fail.rs:11:11
+ |
+LL | extern "C" {
+ | ---------- `extern` block begins here
+...
+LL | type C<T: Ord> where T: 'static;
+ | ^^^^^^^^ help: remove the generic parameters
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: `type`s inside `extern` blocks cannot have `where` clauses
+ --> $DIR/foreign-ty-semantic-fail.rs:11:20
+ |
+LL | extern "C" {
+ | ---------- `extern` block begins here
+...
+LL | type C<T: Ord> where T: 'static;
+ | ^^^^^^^^^^^^^^^^ help: remove the `where` clause
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: incorrect `type` inside `extern` block
+ --> $DIR/foreign-ty-semantic-fail.rs:14:10
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body
+...
+LL | type D = u8;
+ | ^ -- the invalid body
+ | |
+ | cannot have a body
+ |
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/foreign-ty-syntactic-pass.rs b/src/test/ui/parser/foreign-ty-syntactic-pass.rs
new file mode 100644
index 000000000..a746de1f1
--- /dev/null
+++ b/src/test/ui/parser/foreign-ty-syntactic-pass.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern "C" {
+ type A: Ord;
+ type A<'a> where 'a: 'static;
+ type A<T: Ord> where T: 'static;
+ type A = u8;
+ type A<'a: 'static, T: Ord + 'static>: Eq + PartialEq where T: 'static + Copy = Vec<u8>;
+}
diff --git a/src/test/ui/parser/if-block-unreachable-expr.rs b/src/test/ui/parser/if-block-unreachable-expr.rs
new file mode 100644
index 000000000..4063a3370
--- /dev/null
+++ b/src/test/ui/parser/if-block-unreachable-expr.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+// This regressed from 1.20 -> 1.21 -- the condition is unreachable,
+// but it's still an expression, and should parse fine.
+
+fn main() {
+ if { if true { return; } else { return; }; } {}
+}
diff --git a/src/test/ui/parser/if-in-in.fixed b/src/test/ui/parser/if-in-in.fixed
new file mode 100644
index 000000000..0bb88c559
--- /dev/null
+++ b/src/test/ui/parser/if-in-in.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+
+fn main() {
+ for i in 1..2 { //~ ERROR expected iterable, found keyword `in`
+ println!("{}", i);
+ }
+}
diff --git a/src/test/ui/parser/if-in-in.rs b/src/test/ui/parser/if-in-in.rs
new file mode 100644
index 000000000..6c0986fe1
--- /dev/null
+++ b/src/test/ui/parser/if-in-in.rs
@@ -0,0 +1,7 @@
+// run-rustfix
+
+fn main() {
+ for i in in 1..2 { //~ ERROR expected iterable, found keyword `in`
+ println!("{}", i);
+ }
+}
diff --git a/src/test/ui/parser/if-in-in.stderr b/src/test/ui/parser/if-in-in.stderr
new file mode 100644
index 000000000..0e69bc4b2
--- /dev/null
+++ b/src/test/ui/parser/if-in-in.stderr
@@ -0,0 +1,10 @@
+error: expected iterable, found keyword `in`
+ --> $DIR/if-in-in.rs:4:14
+ |
+LL | for i in in 1..2 {
+ | ---^^
+ | |
+ | help: remove the duplicated `in`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/impl-item-const-pass.rs b/src/test/ui/parser/impl-item-const-pass.rs
new file mode 100644
index 000000000..d11245613
--- /dev/null
+++ b/src/test/ui/parser/impl-item-const-pass.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl X {
+ const Y: u8;
+}
diff --git a/src/test/ui/parser/impl-item-const-semantic-fail.rs b/src/test/ui/parser/impl-item-const-semantic-fail.rs
new file mode 100644
index 000000000..5d4692f9f
--- /dev/null
+++ b/src/test/ui/parser/impl-item-const-semantic-fail.rs
@@ -0,0 +1,7 @@
+fn main() {}
+
+struct X;
+
+impl X {
+ const Y: u8; //~ ERROR associated constant in `impl` without body
+}
diff --git a/src/test/ui/parser/impl-item-const-semantic-fail.stderr b/src/test/ui/parser/impl-item-const-semantic-fail.stderr
new file mode 100644
index 000000000..ec3bee0ce
--- /dev/null
+++ b/src/test/ui/parser/impl-item-const-semantic-fail.stderr
@@ -0,0 +1,10 @@
+error: associated constant in `impl` without body
+ --> $DIR/impl-item-const-semantic-fail.rs:6:5
+ |
+LL | const Y: u8;
+ | ^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/impl-item-fn-no-body-pass.rs b/src/test/ui/parser/impl-item-fn-no-body-pass.rs
new file mode 100644
index 000000000..16b09d64e
--- /dev/null
+++ b/src/test/ui/parser/impl-item-fn-no-body-pass.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl X {
+ fn f();
+}
diff --git a/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs
new file mode 100644
index 000000000..cb183db59
--- /dev/null
+++ b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs
@@ -0,0 +1,7 @@
+fn main() {}
+
+struct X;
+
+impl X {
+ fn f(); //~ ERROR associated function in `impl` without body
+}
diff --git a/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr
new file mode 100644
index 000000000..1acb72736
--- /dev/null
+++ b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr
@@ -0,0 +1,10 @@
+error: associated function in `impl` without body
+ --> $DIR/impl-item-fn-no-body-semantic-fail.rs:6:5
+ |
+LL | fn f();
+ | ^^^^^^-
+ | |
+ | help: provide a definition for the function: `{ <body> }`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/impl-item-type-no-body-pass.rs b/src/test/ui/parser/impl-item-type-no-body-pass.rs
new file mode 100644
index 000000000..74a9c6ab7
--- /dev/null
+++ b/src/test/ui/parser/impl-item-type-no-body-pass.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl X {
+ type Y;
+ type Z: Ord;
+ type W: Ord where Self: Eq;
+ type W where Self: Eq;
+}
diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
new file mode 100644
index 000000000..9871cb8fe
--- /dev/null
+++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+
+fn main() {}
+
+struct X;
+
+impl X {
+ type Y;
+ //~^ ERROR associated type in `impl` without body
+ //~| ERROR inherent associated types are unstable
+ type Z: Ord;
+ //~^ ERROR associated type in `impl` without body
+ //~| ERROR bounds on `type`s in `impl`s have no effect
+ //~| ERROR inherent associated types are unstable
+ type W: Ord where Self: Eq;
+ //~^ ERROR associated type in `impl` without body
+ //~| ERROR bounds on `type`s in `impl`s have no effect
+ //~| ERROR inherent associated types are unstable
+ type W where Self: Eq;
+ //~^ ERROR associated type in `impl` without body
+ //~| ERROR inherent associated types are unstable
+}
diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
new file mode 100644
index 000000000..4b398d791
--- /dev/null
+++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
@@ -0,0 +1,83 @@
+error: associated type in `impl` without body
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:8:5
+ |
+LL | type Y;
+ | ^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error: associated type in `impl` without body
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:5
+ |
+LL | type Z: Ord;
+ | ^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error: bounds on `type`s in `impl`s have no effect
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:13
+ |
+LL | type Z: Ord;
+ | ^^^
+
+error: associated type in `impl` without body
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:5
+ |
+LL | type W: Ord where Self: Eq;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error: bounds on `type`s in `impl`s have no effect
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:13
+ |
+LL | type W: Ord where Self: Eq;
+ | ^^^
+
+error: associated type in `impl` without body
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:19:5
+ |
+LL | type W where Self: Eq;
+ | ^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error[E0658]: inherent associated types are unstable
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:8:5
+ |
+LL | type Y;
+ | ^^^^^^^
+ |
+ = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+ = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+
+error[E0658]: inherent associated types are unstable
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:11:5
+ |
+LL | type Z: Ord;
+ | ^^^^^^^^^^^^
+ |
+ = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+ = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+
+error[E0658]: inherent associated types are unstable
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:15:5
+ |
+LL | type W: Ord where Self: Eq;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+ = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+
+error[E0658]: inherent associated types are unstable
+ --> $DIR/impl-item-type-no-body-semantic-fail.rs:19:5
+ |
+LL | type W where Self: Eq;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+ = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/parser/impl-parsing.rs b/src/test/ui/parser/impl-parsing.rs
new file mode 100644
index 000000000..80ce88855
--- /dev/null
+++ b/src/test/ui/parser/impl-parsing.rs
@@ -0,0 +1,10 @@
+impl ! {} // OK
+impl ! where u8: Copy {} // OK
+
+impl Trait Type {} //~ ERROR missing `for` in a trait impl
+impl Trait .. {} //~ ERROR missing `for` in a trait impl
+impl ?Sized for Type {} //~ ERROR expected a trait, found type
+impl ?Sized for .. {} //~ ERROR expected a trait, found type
+
+default unsafe FAIL //~ ERROR expected item, found keyword `unsafe`
+//~^ ERROR `default` is not followed by an item
diff --git a/src/test/ui/parser/impl-parsing.stderr b/src/test/ui/parser/impl-parsing.stderr
new file mode 100644
index 000000000..755addf14
--- /dev/null
+++ b/src/test/ui/parser/impl-parsing.stderr
@@ -0,0 +1,40 @@
+error: missing `for` in a trait impl
+ --> $DIR/impl-parsing.rs:4:11
+ |
+LL | impl Trait Type {}
+ | ^ help: add `for` here
+
+error: missing `for` in a trait impl
+ --> $DIR/impl-parsing.rs:5:11
+ |
+LL | impl Trait .. {}
+ | ^ help: add `for` here
+
+error: expected a trait, found type
+ --> $DIR/impl-parsing.rs:6:6
+ |
+LL | impl ?Sized for Type {}
+ | ^^^^^^
+
+error: expected a trait, found type
+ --> $DIR/impl-parsing.rs:7:6
+ |
+LL | impl ?Sized for .. {}
+ | ^^^^^^
+
+error: `default` is not followed by an item
+ --> $DIR/impl-parsing.rs:9:1
+ |
+LL | default unsafe FAIL
+ | ^^^^^^^ the `default` qualifier
+ |
+ = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: expected item, found keyword `unsafe`
+ --> $DIR/impl-parsing.rs:9:9
+ |
+LL | default unsafe FAIL
+ | ^^^^^^ expected item
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/impl-qpath.rs b/src/test/ui/parser/impl-qpath.rs
new file mode 100644
index 000000000..d1f0a0204
--- /dev/null
+++ b/src/test/ui/parser/impl-qpath.rs
@@ -0,0 +1,7 @@
+// check-pass
+// compile-flags: -Z parse-only
+
+impl <*const u8>::AssocTy {} // OK
+impl <Type as Trait>::AssocTy {} // OK
+impl <'a + Trait>::AssocTy {} // OK
+impl <<Type>::AssocTy>::AssocTy {} // OK
diff --git a/src/test/ui/parser/import-from-path.rs b/src/test/ui/parser/import-from-path.rs
new file mode 100644
index 000000000..3fce08259
--- /dev/null
+++ b/src/test/ui/parser/import-from-path.rs
@@ -0,0 +1,2 @@
+// error-pattern:expected
+use foo::{bar}::baz
diff --git a/src/test/ui/parser/import-from-path.stderr b/src/test/ui/parser/import-from-path.stderr
new file mode 100644
index 000000000..93bdf82d0
--- /dev/null
+++ b/src/test/ui/parser/import-from-path.stderr
@@ -0,0 +1,10 @@
+error: expected `;`, found `::`
+ --> $DIR/import-from-path.rs:2:15
+ |
+LL | use foo::{bar}::baz
+ | ^^ expected `;`
+ |
+ = note: glob-like brace syntax must be last on the path
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/import-from-rename.rs b/src/test/ui/parser/import-from-rename.rs
new file mode 100644
index 000000000..27425a3c9
--- /dev/null
+++ b/src/test/ui/parser/import-from-rename.rs
@@ -0,0 +1,10 @@
+// error-pattern:expected
+
+use foo::{bar} as baz;
+
+mod foo {
+ pub fn bar() {}
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/import-from-rename.stderr b/src/test/ui/parser/import-from-rename.stderr
new file mode 100644
index 000000000..d78f6de92
--- /dev/null
+++ b/src/test/ui/parser/import-from-rename.stderr
@@ -0,0 +1,10 @@
+error: expected `;`, found keyword `as`
+ --> $DIR/import-from-rename.rs:3:16
+ |
+LL | use foo::{bar} as baz;
+ | ^^ expected `;`
+ |
+ = note: glob-like brace syntax must be last on the path
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/import-glob-path.rs b/src/test/ui/parser/import-glob-path.rs
new file mode 100644
index 000000000..de4c07aa7
--- /dev/null
+++ b/src/test/ui/parser/import-glob-path.rs
@@ -0,0 +1,2 @@
+// error-pattern:expected
+use foo::*::bar
diff --git a/src/test/ui/parser/import-glob-path.stderr b/src/test/ui/parser/import-glob-path.stderr
new file mode 100644
index 000000000..a93ef255c
--- /dev/null
+++ b/src/test/ui/parser/import-glob-path.stderr
@@ -0,0 +1,10 @@
+error: expected `;`, found `::`
+ --> $DIR/import-glob-path.rs:2:11
+ |
+LL | use foo::*::bar
+ | ^^ expected `;`
+ |
+ = note: the wildcard token must be last on the path
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/import-glob-rename.rs b/src/test/ui/parser/import-glob-rename.rs
new file mode 100644
index 000000000..b9b753dcd
--- /dev/null
+++ b/src/test/ui/parser/import-glob-rename.rs
@@ -0,0 +1,10 @@
+// error-pattern:expected
+
+use foo::* as baz;
+
+mod foo {
+ pub fn bar() {}
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/import-glob-rename.stderr b/src/test/ui/parser/import-glob-rename.stderr
new file mode 100644
index 000000000..e1a026b63
--- /dev/null
+++ b/src/test/ui/parser/import-glob-rename.stderr
@@ -0,0 +1,10 @@
+error: expected `;`, found keyword `as`
+ --> $DIR/import-glob-rename.rs:3:12
+ |
+LL | use foo::* as baz;
+ | ^^ expected `;`
+ |
+ = note: the wildcard token must be last on the path
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/increment-autofix.fixed b/src/test/ui/parser/increment-autofix.fixed
new file mode 100644
index 000000000..7a426badf
--- /dev/null
+++ b/src/test/ui/parser/increment-autofix.fixed
@@ -0,0 +1,31 @@
+// run-rustfix
+
+pub fn pre_regular() {
+ let mut i = 0;
+ i += 1; //~ ERROR Rust has no prefix increment operator
+ println!("{}", i);
+}
+
+pub fn pre_while() {
+ let mut i = 0;
+ while { i += 1; i } < 5 {
+ //~^ ERROR Rust has no prefix increment operator
+ println!("{}", i);
+ }
+}
+
+pub fn pre_regular_tmp() {
+ let mut tmp = 0;
+ tmp += 1; //~ ERROR Rust has no prefix increment operator
+ println!("{}", tmp);
+}
+
+pub fn pre_while_tmp() {
+ let mut tmp = 0;
+ while { tmp += 1; tmp } < 5 {
+ //~^ ERROR Rust has no prefix increment operator
+ println!("{}", tmp);
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/increment-autofix.rs b/src/test/ui/parser/increment-autofix.rs
new file mode 100644
index 000000000..d38603697
--- /dev/null
+++ b/src/test/ui/parser/increment-autofix.rs
@@ -0,0 +1,31 @@
+// run-rustfix
+
+pub fn pre_regular() {
+ let mut i = 0;
+ ++i; //~ ERROR Rust has no prefix increment operator
+ println!("{}", i);
+}
+
+pub fn pre_while() {
+ let mut i = 0;
+ while ++i < 5 {
+ //~^ ERROR Rust has no prefix increment operator
+ println!("{}", i);
+ }
+}
+
+pub fn pre_regular_tmp() {
+ let mut tmp = 0;
+ ++tmp; //~ ERROR Rust has no prefix increment operator
+ println!("{}", tmp);
+}
+
+pub fn pre_while_tmp() {
+ let mut tmp = 0;
+ while ++tmp < 5 {
+ //~^ ERROR Rust has no prefix increment operator
+ println!("{}", tmp);
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/increment-autofix.stderr b/src/test/ui/parser/increment-autofix.stderr
new file mode 100644
index 000000000..1dc69fd9f
--- /dev/null
+++ b/src/test/ui/parser/increment-autofix.stderr
@@ -0,0 +1,52 @@
+error: Rust has no prefix increment operator
+ --> $DIR/increment-autofix.rs:5:5
+ |
+LL | ++i;
+ | ^^ not a valid prefix operator
+ |
+help: use `+= 1` instead
+ |
+LL - ++i;
+LL + i += 1;
+ |
+
+error: Rust has no prefix increment operator
+ --> $DIR/increment-autofix.rs:11:11
+ |
+LL | while ++i < 5 {
+ | ----- ^^ not a valid prefix operator
+ | |
+ | while parsing the condition of this `while` expression
+ |
+help: use `+= 1` instead
+ |
+LL | while { i += 1; i } < 5 {
+ | ~ +++++++++
+
+error: Rust has no prefix increment operator
+ --> $DIR/increment-autofix.rs:19:5
+ |
+LL | ++tmp;
+ | ^^ not a valid prefix operator
+ |
+help: use `+= 1` instead
+ |
+LL - ++tmp;
+LL + tmp += 1;
+ |
+
+error: Rust has no prefix increment operator
+ --> $DIR/increment-autofix.rs:25:11
+ |
+LL | while ++tmp < 5 {
+ | ----- ^^ not a valid prefix operator
+ | |
+ | while parsing the condition of this `while` expression
+ |
+help: use `+= 1` instead
+ |
+LL | while { tmp += 1; tmp } < 5 {
+ | ~ +++++++++++
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/increment-notfixed.rs b/src/test/ui/parser/increment-notfixed.rs
new file mode 100644
index 000000000..15f159e53
--- /dev/null
+++ b/src/test/ui/parser/increment-notfixed.rs
@@ -0,0 +1,61 @@
+struct Foo {
+ bar: Bar,
+}
+
+struct Bar {
+ qux: i32,
+}
+
+pub fn post_regular() {
+ let mut i = 0;
+ i++; //~ ERROR Rust has no postfix increment operator
+ println!("{}", i);
+}
+
+pub fn post_while() {
+ let mut i = 0;
+ while i++ < 5 {
+ //~^ ERROR Rust has no postfix increment operator
+ println!("{}", i);
+ }
+}
+
+pub fn post_regular_tmp() {
+ let mut tmp = 0;
+ tmp++; //~ ERROR Rust has no postfix increment operator
+ println!("{}", tmp);
+}
+
+pub fn post_while_tmp() {
+ let mut tmp = 0;
+ while tmp++ < 5 {
+ //~^ ERROR Rust has no postfix increment operator
+ println!("{}", tmp);
+ }
+}
+
+pub fn post_field() {
+ let foo = Foo { bar: Bar { qux: 0 } };
+ foo.bar.qux++;
+ //~^ ERROR Rust has no postfix increment operator
+ println!("{}", foo.bar.qux);
+}
+
+pub fn post_field_tmp() {
+ struct S {
+ tmp: i32
+ }
+ let s = S { tmp: 0 };
+ s.tmp++;
+ //~^ ERROR Rust has no postfix increment operator
+ println!("{}", s.tmp);
+}
+
+pub fn pre_field() {
+ let foo = Foo { bar: Bar { qux: 0 } };
+ ++foo.bar.qux;
+ //~^ ERROR Rust has no prefix increment operator
+ println!("{}", foo.bar.qux);
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/increment-notfixed.stderr b/src/test/ui/parser/increment-notfixed.stderr
new file mode 100644
index 000000000..352d98cf8
--- /dev/null
+++ b/src/test/ui/parser/increment-notfixed.stderr
@@ -0,0 +1,102 @@
+error: Rust has no postfix increment operator
+ --> $DIR/increment-notfixed.rs:11:6
+ |
+LL | i++;
+ | ^^ not a valid postfix operator
+ |
+help: use `+= 1` instead
+ |
+LL | { let tmp = i; i += 1; tmp };
+ | +++++++++++ ~~~~~~~~~~~~~~~
+LL - i++;
+LL + i += 1;
+ |
+
+error: Rust has no postfix increment operator
+ --> $DIR/increment-notfixed.rs:17:12
+ |
+LL | while i++ < 5 {
+ | ----- ^^ not a valid postfix operator
+ | |
+ | while parsing the condition of this `while` expression
+ |
+help: use `+= 1` instead
+ |
+LL | while { let tmp = i; i += 1; tmp } < 5 {
+ | +++++++++++ ~~~~~~~~~~~~~~~
+LL - while i++ < 5 {
+LL + while i += 1 < 5 {
+ |
+
+error: Rust has no postfix increment operator
+ --> $DIR/increment-notfixed.rs:25:8
+ |
+LL | tmp++;
+ | ^^ not a valid postfix operator
+ |
+help: use `+= 1` instead
+ |
+LL | { let tmp_ = tmp; tmp += 1; tmp_ };
+ | ++++++++++++ ~~~~~~~~~~~~~~~~~~
+LL - tmp++;
+LL + tmp += 1;
+ |
+
+error: Rust has no postfix increment operator
+ --> $DIR/increment-notfixed.rs:31:14
+ |
+LL | while tmp++ < 5 {
+ | ----- ^^ not a valid postfix operator
+ | |
+ | while parsing the condition of this `while` expression
+ |
+help: use `+= 1` instead
+ |
+LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 {
+ | ++++++++++++ ~~~~~~~~~~~~~~~~~~
+LL - while tmp++ < 5 {
+LL + while tmp += 1 < 5 {
+ |
+
+error: Rust has no postfix increment operator
+ --> $DIR/increment-notfixed.rs:39:16
+ |
+LL | foo.bar.qux++;
+ | ^^ not a valid postfix operator
+ |
+help: use `+= 1` instead
+ |
+LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp };
+ | +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - foo.bar.qux++;
+LL + foo.bar.qux += 1;
+ |
+
+error: Rust has no postfix increment operator
+ --> $DIR/increment-notfixed.rs:49:10
+ |
+LL | s.tmp++;
+ | ^^ not a valid postfix operator
+ |
+help: use `+= 1` instead
+ |
+LL | { let tmp = s.tmp; s.tmp += 1; tmp };
+ | +++++++++++ ~~~~~~~~~~~~~~~~~~~
+LL - s.tmp++;
+LL + s.tmp += 1;
+ |
+
+error: Rust has no prefix increment operator
+ --> $DIR/increment-notfixed.rs:56:5
+ |
+LL | ++foo.bar.qux;
+ | ^^ not a valid prefix operator
+ |
+help: use `+= 1` instead
+ |
+LL - ++foo.bar.qux;
+LL + foo.bar.qux += 1;
+ |
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.rs b/src/test/ui/parser/inner-attr-after-doc-comment.rs
new file mode 100644
index 000000000..36f4191f0
--- /dev/null
+++ b/src/test/ui/parser/inner-attr-after-doc-comment.rs
@@ -0,0 +1,8 @@
+#![feature(lang_items)]
+/**
+ * My module
+ */
+
+#![recursion_limit="100"]
+//~^ ERROR an inner attribute is not permitted following an outer doc comment
+fn main() {}
diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.stderr b/src/test/ui/parser/inner-attr-after-doc-comment.stderr
new file mode 100644
index 000000000..2cfafac77
--- /dev/null
+++ b/src/test/ui/parser/inner-attr-after-doc-comment.stderr
@@ -0,0 +1,23 @@
+error: an inner attribute is not permitted following an outer doc comment
+ --> $DIR/inner-attr-after-doc-comment.rs:6:1
+ |
+LL | / /**
+LL | | * My module
+LL | | */
+ | |___- previous doc comment
+LL |
+LL | #![recursion_limit="100"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute
+LL |
+LL | fn main() {}
+ | ------------ the inner attribute doesn't annotate this function
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the function, change the attribute from inner to outer style
+ |
+LL - #![recursion_limit="100"]
+LL + #[recursion_limit="100"]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/inner-attr-in-trait-def.rs b/src/test/ui/parser/inner-attr-in-trait-def.rs
new file mode 100644
index 000000000..8dba6b362
--- /dev/null
+++ b/src/test/ui/parser/inner-attr-in-trait-def.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![deny(non_camel_case_types)]
+
+fn main() {}
+
+trait foo_bar {
+ #![allow(non_camel_case_types)]
+}
diff --git a/src/test/ui/parser/inner-attr.rs b/src/test/ui/parser/inner-attr.rs
new file mode 100644
index 000000000..1b405e20e
--- /dev/null
+++ b/src/test/ui/parser/inner-attr.rs
@@ -0,0 +1,4 @@
+#[feature(lang_items)]
+
+#![recursion_limit="100"] //~ ERROR an inner attribute is not permitted following an outer attribute
+fn main() {}
diff --git a/src/test/ui/parser/inner-attr.stderr b/src/test/ui/parser/inner-attr.stderr
new file mode 100644
index 000000000..331c254a5
--- /dev/null
+++ b/src/test/ui/parser/inner-attr.stderr
@@ -0,0 +1,20 @@
+error: an inner attribute is not permitted following an outer attribute
+ --> $DIR/inner-attr.rs:3:1
+ |
+LL | #[feature(lang_items)]
+ | ---------------------- previous outer attribute
+LL |
+LL | #![recursion_limit="100"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute
+LL | fn main() {}
+ | ------------ the inner attribute doesn't annotate this function
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the function, change the attribute from inner to outer style
+ |
+LL - #![recursion_limit="100"]
+LL + #[recursion_limit="100"]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/int-literal-too-large-span.rs b/src/test/ui/parser/int-literal-too-large-span.rs
new file mode 100644
index 000000000..666ca9350
--- /dev/null
+++ b/src/test/ui/parser/int-literal-too-large-span.rs
@@ -0,0 +1,7 @@
+// issue #17123
+
+fn main() {
+ 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
+ //~^ ERROR integer literal is too large
+ ; // the span shouldn't point to this.
+}
diff --git a/src/test/ui/parser/int-literal-too-large-span.stderr b/src/test/ui/parser/int-literal-too-large-span.stderr
new file mode 100644
index 000000000..7cae85fc9
--- /dev/null
+++ b/src/test/ui/parser/int-literal-too-large-span.stderr
@@ -0,0 +1,8 @@
+error: integer literal is too large
+ --> $DIR/int-literal-too-large-span.rs:4:5
+ |
+LL | 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns.rs
new file mode 100644
index 000000000..a6d27aab4
--- /dev/null
+++ b/src/test/ui/parser/intersection-patterns.rs
@@ -0,0 +1,40 @@
+// This tests the parser recovery in `recover_intersection_pat`
+// and serves as a regression test for the diagnostics issue #65400.
+//
+// The general idea is that for `$pat_lhs @ $pat_rhs` where
+// `$pat_lhs` is not generated by `ref? mut? $ident` we want
+// to suggest either switching the order or note that intersection
+// patterns are not allowed.
+
+fn main() {
+ let s: Option<u8> = None;
+
+ match s {
+ Some(x) @ y => {}
+ //~^ ERROR pattern on wrong side of `@`
+ //~| pattern on the left, should be on the right
+ //~| binding on the right, should be on the left
+ //~| HELP switch the order
+ //~| SUGGESTION y @ Some(x)
+ _ => {}
+ }
+
+ match s {
+ Some(x) @ Some(y) => {}
+ //~^ ERROR left-hand side of `@` must be a binding
+ //~| interpreted as a pattern, not a binding
+ //~| also a pattern
+ //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+ _ => {}
+ }
+
+ match 2 {
+ 1 ..= 5 @ e => {}
+ //~^ ERROR pattern on wrong side of `@`
+ //~| pattern on the left, should be on the right
+ //~| binding on the right, should be on the left
+ //~| HELP switch the order
+ //~| SUGGESTION e @ 1..=5
+ _ => {}
+ }
+}
diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns.stderr
new file mode 100644
index 000000000..9dc4c469a
--- /dev/null
+++ b/src/test/ui/parser/intersection-patterns.stderr
@@ -0,0 +1,33 @@
+error: pattern on wrong side of `@`
+ --> $DIR/intersection-patterns.rs:13:9
+ |
+LL | Some(x) @ y => {}
+ | -------^^^-
+ | | |
+ | | binding on the right, should be on the left
+ | pattern on the left, should be on the right
+ | help: switch the order: `y @ Some(x)`
+
+error: left-hand side of `@` must be a binding
+ --> $DIR/intersection-patterns.rs:23:9
+ |
+LL | Some(x) @ Some(y) => {}
+ | -------^^^-------
+ | | |
+ | | also a pattern
+ | interpreted as a pattern, not a binding
+ |
+ = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+
+error: pattern on wrong side of `@`
+ --> $DIR/intersection-patterns.rs:32:9
+ |
+LL | 1 ..= 5 @ e => {}
+ | -------^^^-
+ | | |
+ | | binding on the right, should be on the left
+ | pattern on the left, should be on the right
+ | help: switch the order: `e @ 1..=5`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs
new file mode 100644
index 000000000..5c4272504
--- /dev/null
+++ b/src/test/ui/parser/inverted-parameters.rs
@@ -0,0 +1,32 @@
+struct S;
+
+impl S {
+ fn foo(&self, &str bar) {}
+ //~^ ERROR expected one of `:`, `@`
+ //~| HELP declare the type after the parameter binding
+ //~| SUGGESTION <identifier>: <type>
+}
+
+fn baz(S quux, xyzzy: i32) {}
+//~^ ERROR expected one of `:`, `@`
+//~| HELP declare the type after the parameter binding
+//~| SUGGESTION <identifier>: <type>
+
+fn one(i32 a b) {}
+//~^ ERROR expected one of `:`, `@`
+
+fn pattern((i32, i32) (a, b)) {}
+//~^ ERROR expected one of `:`
+
+fn fizz(i32) {}
+//~^ ERROR expected one of `:`, `@`
+//~| HELP if this is a parameter name, give it a type
+//~| HELP if this is a `self` type, give it a parameter name
+//~| HELP if this is a type, explicitly ignore the parameter name
+
+fn missing_colon(quux S) {}
+//~^ ERROR expected one of `:`, `@`
+//~| HELP declare the type after the parameter binding
+//~| SUGGESTION <identifier>: <type>
+
+fn main() {}
diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr
new file mode 100644
index 000000000..866227782
--- /dev/null
+++ b/src/test/ui/parser/inverted-parameters.stderr
@@ -0,0 +1,61 @@
+error: expected one of `:`, `@`, or `|`, found `bar`
+ --> $DIR/inverted-parameters.rs:4:24
+ |
+LL | fn foo(&self, &str bar) {}
+ | -----^^^
+ | | |
+ | | expected one of `:`, `@`, or `|`
+ | help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: expected one of `:`, `@`, or `|`, found `quux`
+ --> $DIR/inverted-parameters.rs:10:10
+ |
+LL | fn baz(S quux, xyzzy: i32) {}
+ | --^^^^
+ | | |
+ | | expected one of `:`, `@`, or `|`
+ | help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: expected one of `:`, `@`, or `|`, found `a`
+ --> $DIR/inverted-parameters.rs:15:12
+ |
+LL | fn one(i32 a b) {}
+ | ^ expected one of `:`, `@`, or `|`
+
+error: expected one of `:` or `|`, found `(`
+ --> $DIR/inverted-parameters.rs:18:23
+ |
+LL | fn pattern((i32, i32) (a, b)) {}
+ | ^ expected one of `:` or `|`
+
+error: expected one of `:`, `@`, or `|`, found `)`
+ --> $DIR/inverted-parameters.rs:21:12
+ |
+LL | fn fizz(i32) {}
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+ |
+LL | fn fizz(self: i32) {}
+ | +++++
+help: if this is a parameter name, give it a type
+ |
+LL | fn fizz(i32: TypeName) {}
+ | ++++++++++
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn fizz(_: i32) {}
+ | ++
+
+error: expected one of `:`, `@`, or `|`, found `S`
+ --> $DIR/inverted-parameters.rs:27:23
+ |
+LL | fn missing_colon(quux S) {}
+ | -----^
+ | | |
+ | | expected one of `:`, `@`, or `|`
+ | help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/issue-61858.rs b/src/test/ui/parser/issue-61858.rs
new file mode 100644
index 000000000..6c3b56586
--- /dev/null
+++ b/src/test/ui/parser/issue-61858.rs
@@ -0,0 +1,3 @@
+fn main() {
+ (if foobar) //~ ERROR expected `{`, found `)`
+}
diff --git a/src/test/ui/parser/issue-61858.stderr b/src/test/ui/parser/issue-61858.stderr
new file mode 100644
index 000000000..03f51c6e3
--- /dev/null
+++ b/src/test/ui/parser/issue-61858.stderr
@@ -0,0 +1,14 @@
+error: expected `{`, found `)`
+ --> $DIR/issue-61858.rs:2:15
+ |
+LL | (if foobar)
+ | ^ expected `{`
+ |
+note: the `if` expression is missing a block after this condition
+ --> $DIR/issue-61858.rs:2:9
+ |
+LL | (if foobar)
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs b/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs
new file mode 100644
index 000000000..57d36feb3
--- /dev/null
+++ b/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs
@@ -0,0 +1,10 @@
+macro_rules! x {
+ ($($c:tt)*) => {
+ $($c)ö* {}
+ //~^ ERROR missing condition for `if` expression
+ };
+}
+
+fn main() {
+ x!(if);
+}
diff --git a/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr
new file mode 100644
index 000000000..6674b924e
--- /dev/null
+++ b/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr
@@ -0,0 +1,10 @@
+error: missing condition for `if` expression
+ --> $DIR/issue-68091-unicode-ident-after-if.rs:3:14
+ |
+LL | $($c)ö* {}
+ | ^ - if this block is the condition of the `if` expression, then it must be followed by another block
+ | |
+ | expected condition here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs
new file mode 100644
index 000000000..1a90b4724
--- /dev/null
+++ b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.rs
@@ -0,0 +1,9 @@
+macro_rules! x {
+ ($($c:tt)*) => {
+ $($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression
+ };
+}
+
+fn main() {
+ x!(!);
+}
diff --git a/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr
new file mode 100644
index 000000000..0b9c364f1
--- /dev/null
+++ b/src/test/ui/parser/issue-68092-unicode-ident-after-incomplete-expr.stderr
@@ -0,0 +1,8 @@
+error: macro expansion ends with an incomplete expression: expected expression
+ --> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:14
+ |
+LL | $($c)ö*
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-81804.rs b/src/test/ui/parser/issue-81804.rs
new file mode 100644
index 000000000..803bde11e
--- /dev/null
+++ b/src/test/ui/parser/issue-81804.rs
@@ -0,0 +1,9 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: expected pattern, found `=`
+// error-pattern: expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
+// error-pattern: expected item, found `]`
+
+fn main() {}
+
+fn p([=(}
diff --git a/src/test/ui/parser/issue-81804.stderr b/src/test/ui/parser/issue-81804.stderr
new file mode 100644
index 000000000..19c4422c6
--- /dev/null
+++ b/src/test/ui/parser/issue-81804.stderr
@@ -0,0 +1,41 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-81804.rs:9:11
+ |
+LL | fn p([=(}
+ | -- ^
+ | ||
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-81804.rs:9:11
+ |
+LL | fn p([=(}
+ | -- ^
+ | ||
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: expected pattern, found `=`
+ --> $DIR/issue-81804.rs:9:7
+ |
+LL | fn p([=(}
+ | ^ expected pattern
+
+error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
+ --> $DIR/issue-81804.rs:9:8
+ |
+LL | fn p([=(}
+ | ^ -^
+ | | |
+ | | help: `)` may belong here
+ | unclosed delimiter
+
+error: expected item, found `]`
+ --> $DIR/issue-81804.rs:9:11
+ |
+LL | fn p([=(}
+ | ^ expected item
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/parser/issue-81827.rs b/src/test/ui/parser/issue-81827.rs
new file mode 100644
index 000000000..7ec581594
--- /dev/null
+++ b/src/test/ui/parser/issue-81827.rs
@@ -0,0 +1,11 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: mismatched closing delimiter: `]`
+// error-pattern: expected one of `)` or `,`, found `{`
+
+#![crate_name="0"]
+
+
+
+fn main() {}
+
+fn r()->i{0|{#[cfg(r(0{]0
diff --git a/src/test/ui/parser/issue-81827.stderr b/src/test/ui/parser/issue-81827.stderr
new file mode 100644
index 000000000..069de3391
--- /dev/null
+++ b/src/test/ui/parser/issue-81827.stderr
@@ -0,0 +1,35 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-81827.rs:11:27
+ |
+LL | fn r()->i{0|{#[cfg(r(0{]0
+ | - - ^
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-81827.rs:11:27
+ |
+LL | fn r()->i{0|{#[cfg(r(0{]0
+ | - - ^
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-81827.rs:11:23
+ |
+LL | fn r()->i{0|{#[cfg(r(0{]0
+ | - ^^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: expected one of `)` or `,`, found `{`
+ --> $DIR/issue-81827.rs:11:23
+ |
+LL | fn r()->i{0|{#[cfg(r(0{]0
+ | ^ expected one of `)` or `,`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issue-87694-duplicated-pub.rs b/src/test/ui/parser/issue-87694-duplicated-pub.rs
new file mode 100644
index 000000000..e3ea61dc4
--- /dev/null
+++ b/src/test/ui/parser/issue-87694-duplicated-pub.rs
@@ -0,0 +1,5 @@
+pub const pub fn test() {}
+//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
+//~| HELP there is already a visibility modifier, remove one
+//~| NOTE explicit visibility first seen here
diff --git a/src/test/ui/parser/issue-87694-duplicated-pub.stderr b/src/test/ui/parser/issue-87694-duplicated-pub.stderr
new file mode 100644
index 000000000..8d242bc9d
--- /dev/null
+++ b/src/test/ui/parser/issue-87694-duplicated-pub.stderr
@@ -0,0 +1,17 @@
+error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+ --> $DIR/issue-87694-duplicated-pub.rs:1:11
+ |
+LL | pub const pub fn test() {}
+ | ^^^
+ | |
+ | expected one of `async`, `extern`, `fn`, or `unsafe`
+ | help: there is already a visibility modifier, remove one
+ |
+note: explicit visibility first seen here
+ --> $DIR/issue-87694-duplicated-pub.rs:1:1
+ |
+LL | pub const pub fn test() {}
+ | ^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-87694-misplaced-pub.rs b/src/test/ui/parser/issue-87694-misplaced-pub.rs
new file mode 100644
index 000000000..3f824617c
--- /dev/null
+++ b/src/test/ui/parser/issue-87694-misplaced-pub.rs
@@ -0,0 +1,5 @@
+const pub fn test() {}
+//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
+//~| HELP visibility `pub` must come before `const`
+//~| SUGGESTION pub const
diff --git a/src/test/ui/parser/issue-87694-misplaced-pub.stderr b/src/test/ui/parser/issue-87694-misplaced-pub.stderr
new file mode 100644
index 000000000..94c6a29ef
--- /dev/null
+++ b/src/test/ui/parser/issue-87694-misplaced-pub.stderr
@@ -0,0 +1,11 @@
+error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+ --> $DIR/issue-87694-misplaced-pub.rs:1:7
+ |
+LL | const pub fn test() {}
+ | ------^^^
+ | | |
+ | | expected one of `async`, `extern`, `fn`, or `unsafe`
+ | help: visibility `pub` must come before `const`: `pub const`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-90728.rs b/src/test/ui/parser/issue-90728.rs
new file mode 100644
index 000000000..d6a898361
--- /dev/null
+++ b/src/test/ui/parser/issue-90728.rs
@@ -0,0 +1,6 @@
+fn main() {
+ a.5.2E+
+ //~^ ERROR: unexpected token: `5.2E+`
+ //~| ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+`
+ //~| ERROR: expected at least one digit in exponent
+}
diff --git a/src/test/ui/parser/issue-90728.stderr b/src/test/ui/parser/issue-90728.stderr
new file mode 100644
index 000000000..b55c46030
--- /dev/null
+++ b/src/test/ui/parser/issue-90728.stderr
@@ -0,0 +1,20 @@
+error: expected at least one digit in exponent
+ --> $DIR/issue-90728.rs:2:7
+ |
+LL | a.5.2E+
+ | ^^^^^
+
+error: unexpected token: `5.2E+`
+ --> $DIR/issue-90728.rs:2:7
+ |
+LL | a.5.2E+
+ | ^^^^^
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+`
+ --> $DIR/issue-90728.rs:2:7
+ |
+LL | a.5.2E+
+ | ^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issue-91421.rs b/src/test/ui/parser/issue-91421.rs
new file mode 100644
index 000000000..8bba27f37
--- /dev/null
+++ b/src/test/ui/parser/issue-91421.rs
@@ -0,0 +1,9 @@
+// Regression test for issue #91421.
+
+fn main() {
+ let value = if true && {
+ //~^ ERROR: this `if` expression is missing a block after the condition
+ //~| HELP: this binary operation is possibly unfinished
+ 3
+ } else { 4 };
+}
diff --git a/src/test/ui/parser/issue-91421.stderr b/src/test/ui/parser/issue-91421.stderr
new file mode 100644
index 000000000..2d9652051
--- /dev/null
+++ b/src/test/ui/parser/issue-91421.stderr
@@ -0,0 +1,14 @@
+error: this `if` expression is missing a block after the condition
+ --> $DIR/issue-91421.rs:4:17
+ |
+LL | let value = if true && {
+ | ^^
+ |
+help: this binary operation is possibly unfinished
+ --> $DIR/issue-91421.rs:4:20
+ |
+LL | let value = if true && {
+ | ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed
new file mode 100644
index 000000000..4b4a416b1
--- /dev/null
+++ b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+pub enum Range {
+ //~^ ERROR `enum` and `struct` are mutually exclusive
+ Valid {
+ begin: u32,
+ len: u32,
+ },
+ Out,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs
new file mode 100644
index 000000000..9cc886641
--- /dev/null
+++ b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.rs
@@ -0,0 +1,13 @@
+// run-rustfix
+
+pub enum struct Range {
+ //~^ ERROR `enum` and `struct` are mutually exclusive
+ Valid {
+ begin: u32,
+ len: u32,
+ },
+ Out,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr
new file mode 100644
index 000000000..edc640bf5
--- /dev/null
+++ b/src/test/ui/parser/issue-99625-enum-struct-mutually-exclusive.stderr
@@ -0,0 +1,8 @@
+error: `enum` and `struct` are mutually exclusive
+ --> $DIR/issue-99625-enum-struct-mutually-exclusive.rs:3:5
+ |
+LL | pub enum struct Range {
+ | ^^^^^^^^^^^ help: replace `enum struct` with: `enum`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs b/src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs
new file mode 100644
index 000000000..32a3b9dcc
--- /dev/null
+++ b/src/test/ui/parser/issues/auxiliary/issue-21146-inc.rs
@@ -0,0 +1,3 @@
+// include file for issue-21146.rs
+
+parse_error
diff --git a/src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs b/src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
new file mode 100644
index 000000000..e5604b816
--- /dev/null
+++ b/src/test/ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
@@ -0,0 +1,13 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(ICE)]
+pub fn derive(_: TokenStream) -> TokenStream {
+ r#"#[allow(missing_docs)] struct X { }"#.parse().unwrap()
+}
diff --git a/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs b/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs
new file mode 100644
index 000000000..9429e5143
--- /dev/null
+++ b/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs
@@ -0,0 +1,3 @@
+// include file for issue-94340.rs
+#![deny(rust_2018_idioms)]
+#![deny(unused_must_use)]
diff --git a/src/test/ui/parser/issues/issue-10392-2.fixed b/src/test/ui/parser/issues/issue-10392-2.fixed
new file mode 100644
index 000000000..3386fac17
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10392-2.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub struct A { pub foo: isize }
+
+fn a() -> A { panic!() }
+
+fn main() {
+ let A { .. } = a(); //~ ERROR: expected `}`
+}
diff --git a/src/test/ui/parser/issues/issue-10392-2.rs b/src/test/ui/parser/issues/issue-10392-2.rs
new file mode 100644
index 000000000..30628ae31
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10392-2.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub struct A { pub foo: isize }
+
+fn a() -> A { panic!() }
+
+fn main() {
+ let A { .., } = a(); //~ ERROR: expected `}`
+}
diff --git a/src/test/ui/parser/issues/issue-10392-2.stderr b/src/test/ui/parser/issues/issue-10392-2.stderr
new file mode 100644
index 000000000..4154ecfeb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10392-2.stderr
@@ -0,0 +1,12 @@
+error: expected `}`, found `,`
+ --> $DIR/issue-10392-2.rs:8:15
+ |
+LL | let A { .., } = a();
+ | --^
+ | | |
+ | | expected `}`
+ | | help: remove this comma
+ | `..` must be at the end and cannot have a trailing comma
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-10392.rs b/src/test/ui/parser/issues/issue-10392.rs
new file mode 100644
index 000000000..5b0c2fc2b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10392.rs
@@ -0,0 +1,7 @@
+struct A { foo: isize }
+
+fn a() -> A { panic!() }
+
+fn main() {
+ let A { , } = a(); //~ ERROR expected ident
+}
diff --git a/src/test/ui/parser/issues/issue-10392.stderr b/src/test/ui/parser/issues/issue-10392.stderr
new file mode 100644
index 000000000..438ea67d3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10392.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `,`
+ --> $DIR/issue-10392.rs:6:13
+ |
+LL | let A { , } = a();
+ | - ^ expected identifier
+ | |
+ | while parsing the fields for this pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-10636-1.rs b/src/test/ui/parser/issues/issue-10636-1.rs
new file mode 100644
index 000000000..77c6072d6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10636-1.rs
@@ -0,0 +1,8 @@
+struct Obj {
+ //~^ NOTE: unclosed delimiter
+ member: usize
+)
+//~^ ERROR mismatched closing delimiter
+//~| NOTE mismatched closing delimiter
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-10636-1.stderr b/src/test/ui/parser/issues/issue-10636-1.stderr
new file mode 100644
index 000000000..1e6294ebe
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10636-1.stderr
@@ -0,0 +1,11 @@
+error: mismatched closing delimiter: `)`
+ --> $DIR/issue-10636-1.rs:1:12
+ |
+LL | struct Obj {
+ | ^ unclosed delimiter
+...
+LL | )
+ | ^ mismatched closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-10636-2.rs b/src/test/ui/parser/issues/issue-10636-2.rs
new file mode 100644
index 000000000..6fb63639d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10636-2.rs
@@ -0,0 +1,11 @@
+// FIXME(31528) we emit a bunch of silly errors here due to continuing past the
+// first one. This would be easy-ish to address by better recovery in tokenisation.
+
+pub fn trace_option(option: Option<isize>) {
+ option.map(|some| 42;
+ //~^ ERROR: expected one of
+
+}
+//~^ ERROR: expected expression, found `)`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-10636-2.stderr b/src/test/ui/parser/issues/issue-10636-2.stderr
new file mode 100644
index 000000000..d4f2da9e3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-10636-2.stderr
@@ -0,0 +1,16 @@
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
+ --> $DIR/issue-10636-2.rs:5:15
+ |
+LL | option.map(|some| 42;
+ | ^ ^ help: `)` may belong here
+ | |
+ | unclosed delimiter
+
+error: expected expression, found `)`
+ --> $DIR/issue-10636-2.rs:8:1
+ |
+LL | }
+ | ^ expected expression
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-13483.rs b/src/test/ui/parser/issues/issue-13483.rs
new file mode 100644
index 000000000..4e32fcab3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-13483.rs
@@ -0,0 +1,17 @@
+fn main() {
+ if true {
+ } else if {
+ //~^ ERROR missing condition for `if` expression
+ } else {
+ }
+}
+
+fn foo() {
+ if true {
+ } else if {
+ //~^ ERROR missing condition for `if` expression
+ }
+ bar();
+}
+
+fn bar() {}
diff --git a/src/test/ui/parser/issues/issue-13483.stderr b/src/test/ui/parser/issues/issue-13483.stderr
new file mode 100644
index 000000000..f5534090f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-13483.stderr
@@ -0,0 +1,18 @@
+error: missing condition for `if` expression
+ --> $DIR/issue-13483.rs:3:14
+ |
+LL | } else if {
+ | ^- if this block is the condition of the `if` expression, then it must be followed by another block
+ | |
+ | expected condition here
+
+error: missing condition for `if` expression
+ --> $DIR/issue-13483.rs:11:14
+ |
+LL | } else if {
+ | ^- if this block is the condition of the `if` expression, then it must be followed by another block
+ | |
+ | expected condition here
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-14303-enum.rs b/src/test/ui/parser/issues/issue-14303-enum.rs
new file mode 100644
index 000000000..a61061598
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-enum.rs
@@ -0,0 +1,6 @@
+enum X<'a, T, 'b> {
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+ A(&'a &'b T)
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-enum.stderr b/src/test/ui/parser/issues/issue-14303-enum.stderr
new file mode 100644
index 000000000..55cef4cab
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-enum.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+ --> $DIR/issue-14303-enum.rs:1:15
+ |
+LL | enum X<'a, T, 'b> {
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-14303-fn-def.rs b/src/test/ui/parser/issues/issue-14303-fn-def.rs
new file mode 100644
index 000000000..221bd311e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-fn-def.rs
@@ -0,0 +1,4 @@
+fn foo<'a, T, 'b>(x: &'a T) {}
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-fn-def.stderr b/src/test/ui/parser/issues/issue-14303-fn-def.stderr
new file mode 100644
index 000000000..bacc92296
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-fn-def.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+ --> $DIR/issue-14303-fn-def.rs:1:15
+ |
+LL | fn foo<'a, T, 'b>(x: &'a T) {}
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-14303-fncall.full.stderr b/src/test/ui/parser/issues/issue-14303-fncall.full.stderr
new file mode 100644
index 000000000..0c152516a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-fncall.full.stderr
@@ -0,0 +1,9 @@
+error[E0747]: type provided when a lifetime was expected
+ --> $DIR/issue-14303-fncall.rs:15:26
+ |
+LL | .collect::<Vec<S<_, 'a>>>();
+ | ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr b/src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr
new file mode 100644
index 000000000..571815776
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-fncall.generic_arg.stderr
@@ -0,0 +1,9 @@
+error[E0747]: inferred provided when a lifetime was expected
+ --> $DIR/issue-14303-fncall.rs:15:26
+ |
+LL | .collect::<Vec<S<_, 'a>>>();
+ | ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/parser/issues/issue-14303-fncall.rs b/src/test/ui/parser/issues/issue-14303-fncall.rs
new file mode 100644
index 000000000..afc4959f1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-fncall.rs
@@ -0,0 +1,20 @@
+// revisions: full generic_arg
+// can't run rustfix because it doesn't handle multipart suggestions correctly
+// we need the above to avoid ast borrowck failure in recovered code
+#![cfg_attr(generic_arg, feature(generic_arg_infer))]
+
+
+struct S<'a, T> {
+ a: &'a T,
+ b: &'a T,
+}
+
+fn foo<'a, 'b>(start: &'a usize, end: &'a usize) {
+ let _x = (*start..*end)
+ .map(|x| S { a: start, b: end })
+ .collect::<Vec<S<_, 'a>>>();
+ //[generic_arg]~^ ERROR inferred provided when a lifetime was expected
+ //[full]~^^ ERROR type provided when a lifetime was expected
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-impl.rs b/src/test/ui/parser/issues/issue-14303-impl.rs
new file mode 100644
index 000000000..4dc2c6660
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-impl.rs
@@ -0,0 +1,6 @@
+struct X<T>(T);
+
+impl<'a, T, 'b> X<T> {}
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-impl.stderr b/src/test/ui/parser/issues/issue-14303-impl.stderr
new file mode 100644
index 000000000..d6be02f70
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-impl.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+ --> $DIR/issue-14303-impl.rs:3:13
+ |
+LL | impl<'a, T, 'b> X<T> {}
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-14303-path.rs b/src/test/ui/parser/issues/issue-14303-path.rs
new file mode 100644
index 000000000..89ef914ab
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-path.rs
@@ -0,0 +1,13 @@
+mod foo {
+ pub struct X<'a, 'b, 'c, T> {
+ a: &'a str,
+ b: &'b str,
+ c: &'c str,
+ t: T,
+ }
+}
+
+fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
+//~^ ERROR type provided when a lifetime was expected
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-path.stderr b/src/test/ui/parser/issues/issue-14303-path.stderr
new file mode 100644
index 000000000..841e63ecb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-path.stderr
@@ -0,0 +1,9 @@
+error[E0747]: type provided when a lifetime was expected
+ --> $DIR/issue-14303-path.rs:10:37
+ |
+LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
+ | ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/parser/issues/issue-14303-struct.rs b/src/test/ui/parser/issues/issue-14303-struct.rs
new file mode 100644
index 000000000..0bd10b4d0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-struct.rs
@@ -0,0 +1,6 @@
+struct X<'a, T, 'b> {
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+ x: &'a &'b T
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-struct.stderr b/src/test/ui/parser/issues/issue-14303-struct.stderr
new file mode 100644
index 000000000..fa62a39f2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-struct.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+ --> $DIR/issue-14303-struct.rs:1:17
+ |
+LL | struct X<'a, T, 'b> {
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-14303-trait.rs b/src/test/ui/parser/issues/issue-14303-trait.rs
new file mode 100644
index 000000000..f253de92d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-trait.rs
@@ -0,0 +1,4 @@
+trait Foo<'a, T, 'b> {}
+//~^ ERROR lifetime parameters must be declared prior to type parameters
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-14303-trait.stderr b/src/test/ui/parser/issues/issue-14303-trait.stderr
new file mode 100644
index 000000000..75cd67a9d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-14303-trait.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+ --> $DIR/issue-14303-trait.rs:1:18
+ |
+LL | trait Foo<'a, T, 'b> {}
+ | --------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-15914.rs b/src/test/ui/parser/issues/issue-15914.rs
new file mode 100644
index 000000000..4a5606af6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-15914.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let ref
+ (); //~ ERROR expected identifier, found `(`
+}
diff --git a/src/test/ui/parser/issues/issue-15914.stderr b/src/test/ui/parser/issues/issue-15914.stderr
new file mode 100644
index 000000000..ea26453f8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-15914.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `(`
+ --> $DIR/issue-15914.rs:3:9
+ |
+LL | ();
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-15980.rs b/src/test/ui/parser/issues/issue-15980.rs
new file mode 100644
index 000000000..87faa7d5f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-15980.rs
@@ -0,0 +1,17 @@
+use std::io;
+
+fn main(){
+ let x: io::Result<()> = Ok(());
+ match x {
+ Err(ref e) if e.kind == io::EndOfFile {
+ //~^ NOTE while parsing this struct
+ return
+ //~^ ERROR expected identifier, found keyword `return`
+ //~| NOTE expected identifier, found keyword
+ }
+ //~^ NOTE expected one of `.`, `=>`, `?`, or an operator
+ _ => {}
+ //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_`
+ //~| NOTE unexpected token
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-15980.stderr b/src/test/ui/parser/issues/issue-15980.stderr
new file mode 100644
index 000000000..c59c81119
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-15980.stderr
@@ -0,0 +1,25 @@
+error: expected identifier, found keyword `return`
+ --> $DIR/issue-15980.rs:8:13
+ |
+LL | Err(ref e) if e.kind == io::EndOfFile {
+ | ------------- while parsing this struct
+LL |
+LL | return
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `return` to use it as an identifier
+ |
+LL | r#return
+ | ++
+
+error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_`
+ --> $DIR/issue-15980.rs:13:9
+ |
+LL | }
+ | - expected one of `.`, `=>`, `?`, or an operator
+LL |
+LL | _ => {}
+ | ^ unexpected token
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-1655.rs b/src/test/ui/parser/issues/issue-1655.rs
new file mode 100644
index 000000000..e9fc6f153
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-1655.rs
@@ -0,0 +1,10 @@
+mod blade_runner {
+ #vec[doc( //~ ERROR expected one of `!` or `[`, found `vec`
+ brief = "Blade Runner is probably the best movie ever",
+ desc = "I like that in the world of Blade Runner it is always
+ raining, and that it's always night time. And Aliens
+ was also a really good movie.
+
+ Alien 3 was crap though."
+ )]
+}
diff --git a/src/test/ui/parser/issues/issue-1655.stderr b/src/test/ui/parser/issues/issue-1655.stderr
new file mode 100644
index 000000000..0c390a0ec
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-1655.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `[`, found `vec`
+ --> $DIR/issue-1655.rs:2:6
+ |
+LL | #vec[doc(
+ | ^^^ expected one of `!` or `[`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-17383.rs b/src/test/ui/parser/issues/issue-17383.rs
new file mode 100644
index 000000000..7bf0e64f2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17383.rs
@@ -0,0 +1,7 @@
+enum X {
+ A = 3,
+ //~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants
+ B(usize)
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-17383.stderr b/src/test/ui/parser/issues/issue-17383.stderr
new file mode 100644
index 000000000..265d6e148
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17383.stderr
@@ -0,0 +1,15 @@
+error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
+ --> $DIR/issue-17383.rs:2:9
+ |
+LL | A = 3,
+ | ^ disallowed custom discriminant
+LL |
+LL | B(usize)
+ | -------- tuple variant defined here
+ |
+ = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
+ = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/parser/issues/issue-17718-const-mut.rs b/src/test/ui/parser/issues/issue-17718-const-mut.rs
new file mode 100644
index 000000000..795a8c763
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17718-const-mut.rs
@@ -0,0 +1,7 @@
+const
+mut //~ ERROR: const globals cannot be mutable
+//~^^ HELP you might want to declare a static instead
+FOO: usize = 3;
+
+fn main() {
+}
diff --git a/src/test/ui/parser/issues/issue-17718-const-mut.stderr b/src/test/ui/parser/issues/issue-17718-const-mut.stderr
new file mode 100644
index 000000000..8251ce999
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17718-const-mut.stderr
@@ -0,0 +1,10 @@
+error: const globals cannot be mutable
+ --> $DIR/issue-17718-const-mut.rs:2:1
+ |
+LL | const
+ | ----- help: you might want to declare a static instead: `static`
+LL | mut
+ | ^^^ cannot be mutable
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-17904-2.rs b/src/test/ui/parser/issues/issue-17904-2.rs
new file mode 100644
index 000000000..186a955c3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17904-2.rs
@@ -0,0 +1,3 @@
+struct Bar<T> { x: T } where T: Copy //~ ERROR expected item, found keyword `where`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-17904-2.stderr b/src/test/ui/parser/issues/issue-17904-2.stderr
new file mode 100644
index 000000000..9c7fdf6cc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17904-2.stderr
@@ -0,0 +1,8 @@
+error: expected item, found keyword `where`
+ --> $DIR/issue-17904-2.rs:1:24
+ |
+LL | struct Bar<T> { x: T } where T: Copy
+ | ^^^^^ expected item
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-17904.rs b/src/test/ui/parser/issues/issue-17904.rs
new file mode 100644
index 000000000..7d6a54f4b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17904.rs
@@ -0,0 +1,6 @@
+struct Baz<U> where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax.
+struct Baz<U> where U: Eq(U) -> R; // Notice this parses as well.
+struct Baz<U>(U) where U: Eq; // This rightfully signals no error as well.
+struct Foo<T> where T: Copy, (T); //~ ERROR expected one of `:`, `==`, or `=`, found `;`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-17904.stderr b/src/test/ui/parser/issues/issue-17904.stderr
new file mode 100644
index 000000000..a3cac6761
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-17904.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `==`, or `=`, found `;`
+ --> $DIR/issue-17904.rs:4:33
+ |
+LL | struct Foo<T> where T: Copy, (T);
+ | ^ expected one of `:`, `==`, or `=`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-1802-1.rs b/src/test/ui/parser/issues/issue-1802-1.rs
new file mode 100644
index 000000000..3c34b0d8f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-1802-1.rs
@@ -0,0 +1,7 @@
+fn log(a: i32, b: i32) {}
+
+fn main() {
+ let error = 42;
+ log(error, 0b);
+ //~^ ERROR no valid digits found for number
+}
diff --git a/src/test/ui/parser/issues/issue-1802-1.stderr b/src/test/ui/parser/issues/issue-1802-1.stderr
new file mode 100644
index 000000000..954cc0bee
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-1802-1.stderr
@@ -0,0 +1,9 @@
+error[E0768]: no valid digits found for number
+ --> $DIR/issue-1802-1.rs:5:16
+ |
+LL | log(error, 0b);
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0768`.
diff --git a/src/test/ui/parser/issues/issue-1802-2.rs b/src/test/ui/parser/issues/issue-1802-2.rs
new file mode 100644
index 000000000..3c34b0d8f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-1802-2.rs
@@ -0,0 +1,7 @@
+fn log(a: i32, b: i32) {}
+
+fn main() {
+ let error = 42;
+ log(error, 0b);
+ //~^ ERROR no valid digits found for number
+}
diff --git a/src/test/ui/parser/issues/issue-1802-2.stderr b/src/test/ui/parser/issues/issue-1802-2.stderr
new file mode 100644
index 000000000..49043d07b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-1802-2.stderr
@@ -0,0 +1,9 @@
+error[E0768]: no valid digits found for number
+ --> $DIR/issue-1802-2.rs:5:16
+ |
+LL | log(error, 0b);
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0768`.
diff --git a/src/test/ui/parser/issues/issue-19096.rs b/src/test/ui/parser/issues/issue-19096.rs
new file mode 100644
index 000000000..c5bfd10ee
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-19096.rs
@@ -0,0 +1,10 @@
+fn main() { // we don't complain about the return type being `{integer}`
+ let t = (42, 42);
+ t.0::<isize>; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `::`
+}
+
+fn foo() -> usize { // we don't complain about the return type being unit
+ let t = (42, 42);
+ t.0::<isize>; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `::`
+ 42;
+}
diff --git a/src/test/ui/parser/issues/issue-19096.stderr b/src/test/ui/parser/issues/issue-19096.stderr
new file mode 100644
index 000000000..4df7f878b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-19096.stderr
@@ -0,0 +1,14 @@
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::`
+ --> $DIR/issue-19096.rs:3:8
+ |
+LL | t.0::<isize>;
+ | ^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::`
+ --> $DIR/issue-19096.rs:8:8
+ |
+LL | t.0::<isize>;
+ | ^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-19398.rs b/src/test/ui/parser/issues/issue-19398.rs
new file mode 100644
index 000000000..46eb320a1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-19398.rs
@@ -0,0 +1,6 @@
+trait T {
+ extern "Rust" unsafe fn foo();
+ //~^ ERROR expected `{`, found keyword `unsafe`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-19398.stderr b/src/test/ui/parser/issues/issue-19398.stderr
new file mode 100644
index 000000000..1da00960a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-19398.stderr
@@ -0,0 +1,13 @@
+error: expected `{`, found keyword `unsafe`
+ --> $DIR/issue-19398.rs:2:19
+ |
+LL | trait T {
+ | - while parsing this item list starting here
+LL | extern "Rust" unsafe fn foo();
+ | ^^^^^^ expected `{`
+LL |
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-1.rs b/src/test/ui/parser/issues/issue-20616-1.rs
new file mode 100644
index 000000000..49e9cb310
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-1.rs
@@ -0,0 +1,36 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+type Type_1<'a T> = &'a T; //~ error: expected one of `,`, `:`, or `>`, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-1.stderr b/src/test/ui/parser/issues/issue-20616-1.stderr
new file mode 100644
index 000000000..816046237
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-1.stderr
@@ -0,0 +1,8 @@
+error: expected one of `,`, `:`, or `>`, found `T`
+ --> $DIR/issue-20616-1.rs:9:16
+ |
+LL | type Type_1<'a T> = &'a T;
+ | ^ expected one of `,`, `:`, or `>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-2.rs b/src/test/ui/parser/issues/issue-20616-2.rs
new file mode 100644
index 000000000..2f2c6903a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-2.rs
@@ -0,0 +1,36 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+type Type_2 = Type_1_<'static ()>; //~ error: expected one of `,` or `>`, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-2.stderr b/src/test/ui/parser/issues/issue-20616-2.stderr
new file mode 100644
index 000000000..42059685c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-2.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,` or `>`, found `(`
+ --> $DIR/issue-20616-2.rs:12:31
+ |
+LL | type Type_2 = Type_1_<'static ()>;
+ | ^ expected one of `,` or `>`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type Type_2 = Type_1_<'static> ()>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-3.rs b/src/test/ui/parser/issues/issue-20616-3.rs
new file mode 100644
index 000000000..b2371051c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-3.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+type Type_3<T> = Box<T,,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-3.stderr b/src/test/ui/parser/issues/issue-20616-3.stderr
new file mode 100644
index 000000000..dbff116e5
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-3.stderr
@@ -0,0 +1,13 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+ --> $DIR/issue-20616-3.rs:13:24
+ |
+LL | type Type_3<T> = Box<T,,>;
+ | ^ expected one of `>`, a const expression, lifetime, or type
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type Type_3<T> = Box<T>,,>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-4.rs b/src/test/ui/parser/issues/issue-20616-4.rs
new file mode 100644
index 000000000..a71f47ca4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-4.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+type Type_4<T> = Type_1_<'static,, T>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-4.stderr b/src/test/ui/parser/issues/issue-20616-4.stderr
new file mode 100644
index 000000000..48a06e00b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-4.stderr
@@ -0,0 +1,13 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+ --> $DIR/issue-20616-4.rs:16:34
+ |
+LL | type Type_4<T> = Type_1_<'static,, T>;
+ | ^ expected one of `>`, a const expression, lifetime, or type
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type Type_4<T> = Type_1_<'static>,, T>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-5.rs b/src/test/ui/parser/issues/issue-20616-5.rs
new file mode 100644
index 000000000..b96d09d59
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-5.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+type Type_5<'a> = Type_1_<'a, (),,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-5.stderr b/src/test/ui/parser/issues/issue-20616-5.stderr
new file mode 100644
index 000000000..84bee2ad1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-5.stderr
@@ -0,0 +1,13 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+ --> $DIR/issue-20616-5.rs:22:34
+ |
+LL | type Type_5<'a> = Type_1_<'a, (),,>;
+ | ^ expected one of `>`, a const expression, lifetime, or type
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type Type_5<'a> = Type_1_<'a, ()>,,>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-6.rs b/src/test/ui/parser/issues/issue-20616-6.rs
new file mode 100644
index 000000000..a2c45ecec
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-6.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+type Type_6 = Type_5_<'a,,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-6.stderr b/src/test/ui/parser/issues/issue-20616-6.stderr
new file mode 100644
index 000000000..67de41b97
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-6.stderr
@@ -0,0 +1,13 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+ --> $DIR/issue-20616-6.rs:25:26
+ |
+LL | type Type_6 = Type_5_<'a,,>;
+ | ^ expected one of `>`, a const expression, lifetime, or type
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type Type_6 = Type_5_<'a>,,>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-7.rs b/src/test/ui/parser/issues/issue-20616-7.rs
new file mode 100644
index 000000000..67209c02a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-7.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+type Type_7 = Box<(),,>;
+//~^ error: expected one of `>`, a const expression, lifetime, or type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected ident, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-7.stderr b/src/test/ui/parser/issues/issue-20616-7.stderr
new file mode 100644
index 000000000..3b8e07fa0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-7.stderr
@@ -0,0 +1,13 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `,`
+ --> $DIR/issue-20616-7.rs:28:22
+ |
+LL | type Type_7 = Box<(),,>;
+ | ^ expected one of `>`, a const expression, lifetime, or type
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type Type_7 = Box<()>,,>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-8.rs b/src/test/ui/parser/issues/issue-20616-8.rs
new file mode 100644
index 000000000..3ceb58d12
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-8.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+type Type_8<'a,,> = &'a ();
+//~^ error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+
+
+//type Type_9<T,,> = Box<T>; // error: expected identifier, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-8.stderr b/src/test/ui/parser/issues/issue-20616-8.stderr
new file mode 100644
index 000000000..e9f37e50f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-8.stderr
@@ -0,0 +1,8 @@
+error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/issue-20616-8.rs:31:16
+ |
+LL | type Type_8<'a,,> = &'a ();
+ | ^ expected one of `#`, `>`, `const`, identifier, or lifetime
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20616-9.rs b/src/test/ui/parser/issues/issue-20616-9.rs
new file mode 100644
index 000000000..7f8428448
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-9.rs
@@ -0,0 +1,35 @@
+// We need all these 9 issue-20616-N.rs files
+// because we can only catch one parsing error at a time
+
+type Type_1_<'a, T> = &'a T;
+
+
+//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T`
+
+
+//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
+
+
+//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
+
+
+//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
+
+
+type Type_5_<'a> = Type_1_<'a, ()>;
+
+
+//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
+
+
+//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
+
+
+//type Type_7 = Box<(),,>; // error: expected type, found `,`
+
+
+//type Type_8<'a,,> = &'a (); // error: expected identifier, found `,`
+
+
+type Type_9<T,,> = Box<T>;
+//~^ error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
diff --git a/src/test/ui/parser/issues/issue-20616-9.stderr b/src/test/ui/parser/issues/issue-20616-9.stderr
new file mode 100644
index 000000000..dc309d1bc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20616-9.stderr
@@ -0,0 +1,8 @@
+error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/issue-20616-9.rs:34:15
+ |
+LL | type Type_9<T,,> = Box<T>;
+ | ^ expected one of `#`, `>`, `const`, identifier, or lifetime
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20711-2.rs b/src/test/ui/parser/issues/issue-20711-2.rs
new file mode 100644
index 000000000..168c7e761
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20711-2.rs
@@ -0,0 +1,10 @@
+struct Foo;
+
+impl Foo {
+ fn foo() {}
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ //~^ ERROR expected item after attributes
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-20711-2.stderr b/src/test/ui/parser/issues/issue-20711-2.stderr
new file mode 100644
index 000000000..12b18bbc5
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20711-2.stderr
@@ -0,0 +1,14 @@
+error: expected item after attributes
+ --> $DIR/issue-20711-2.rs:6:5
+ |
+LL | impl Foo {
+ | - while parsing this item list starting here
+...
+LL | #[stable(feature = "rust1", since = "1.0.0")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-20711.rs b/src/test/ui/parser/issues/issue-20711.rs
new file mode 100644
index 000000000..020bb79d6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20711.rs
@@ -0,0 +1,8 @@
+struct Foo;
+
+impl Foo {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ //~^ ERROR expected item after attributes
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-20711.stderr b/src/test/ui/parser/issues/issue-20711.stderr
new file mode 100644
index 000000000..4af4b22be
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-20711.stderr
@@ -0,0 +1,13 @@
+error: expected item after attributes
+ --> $DIR/issue-20711.rs:4:5
+ |
+LL | impl Foo {
+ | - while parsing this item list starting here
+LL | #[stable(feature = "rust1", since = "1.0.0")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-21146.rs b/src/test/ui/parser/issues/issue-21146.rs
new file mode 100644
index 000000000..19eaffc3e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-21146.rs
@@ -0,0 +1,3 @@
+// error-pattern: expected one of `!` or `::`, found `<eof>`
+include!("auxiliary/issue-21146-inc.rs");
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-21146.stderr b/src/test/ui/parser/issues/issue-21146.stderr
new file mode 100644
index 000000000..c71fda3d6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-21146.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found `<eof>`
+ --> $DIR/auxiliary/issue-21146-inc.rs:3:1
+ |
+LL | parse_error
+ | ^^^^^^^^^^^ expected one of `!` or `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-21153.rs b/src/test/ui/parser/issues/issue-21153.rs
new file mode 100644
index 000000000..bf5fdb1f3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-21153.rs
@@ -0,0 +1,6 @@
+trait MyTrait<T>: Iterator {
+ Item = T;
+ //~^ ERROR expected one of `!` or `::`, found `=`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-21153.stderr b/src/test/ui/parser/issues/issue-21153.stderr
new file mode 100644
index 000000000..cbfa9ded3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-21153.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `=`
+ --> $DIR/issue-21153.rs:2:10
+ |
+LL | trait MyTrait<T>: Iterator {
+ | - while parsing this item list starting here
+LL | Item = T;
+ | ^ expected one of `!` or `::`
+LL |
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-21475.rs b/src/test/ui/parser/issues/issue-21475.rs
new file mode 100644
index 000000000..b028fcae0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-21475.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(unused_imports, overlapping_range_endpoints)]
+// pretty-expanded FIXME #23616
+
+use m::{START, END};
+
+fn main() {
+ match 42 {
+ m::START..=m::END => {},
+ 0..=m::END => {},
+ m::START..=59 => {},
+ _ => {},
+ }
+}
+
+mod m {
+ pub const START: u32 = 4;
+ pub const END: u32 = 14;
+}
diff --git a/src/test/ui/parser/issues/issue-22647.rs b/src/test/ui/parser/issues/issue-22647.rs
new file mode 100644
index 000000000..a68614106
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-22647.rs
@@ -0,0 +1,15 @@
+fn main() {
+ let caller<F> = |f: F| //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
+ where F: Fn() -> i32
+ {
+ let x = f();
+ println!("Y {}",x);
+ return x;
+ };
+
+ caller(bar_handler);
+}
+
+fn bar_handler() -> i32 {
+ 5
+}
diff --git a/src/test/ui/parser/issues/issue-22647.stderr b/src/test/ui/parser/issues/issue-22647.stderr
new file mode 100644
index 000000000..89b454d19
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-22647.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
+ --> $DIR/issue-22647.rs:2:15
+ |
+LL | let caller<F> = |f: F|
+ | ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-22712.rs b/src/test/ui/parser/issues/issue-22712.rs
new file mode 100644
index 000000000..774de9c7e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-22712.rs
@@ -0,0 +1,9 @@
+struct Foo<B> {
+ buffer: B
+}
+
+fn bar() {
+ let Foo<Vec<u8>> //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-22712.stderr b/src/test/ui/parser/issues/issue-22712.stderr
new file mode 100644
index 000000000..30fabac65
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-22712.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
+ --> $DIR/issue-22712.rs:6:12
+ |
+LL | let Foo<Vec<u8>>
+ | ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-2354-1.rs b/src/test/ui/parser/issues/issue-2354-1.rs
new file mode 100644
index 000000000..996cf1bcb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-2354-1.rs
@@ -0,0 +1 @@
+static foo: isize = 2; } //~ ERROR unexpected closing delimiter:
diff --git a/src/test/ui/parser/issues/issue-2354-1.stderr b/src/test/ui/parser/issues/issue-2354-1.stderr
new file mode 100644
index 000000000..7ea0f2a98
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-2354-1.stderr
@@ -0,0 +1,8 @@
+error: unexpected closing delimiter: `}`
+ --> $DIR/issue-2354-1.rs:1:24
+ |
+LL | static foo: isize = 2; }
+ | ^ unexpected closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-2354.rs b/src/test/ui/parser/issues/issue-2354.rs
new file mode 100644
index 000000000..c422040cb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-2354.rs
@@ -0,0 +1,15 @@
+fn foo() { //~ NOTE unclosed delimiter
+ match Some(10) {
+ //~^ NOTE this delimiter might not be properly closed...
+ Some(y) => { panic!(); }
+ None => { panic!(); }
+}
+//~^ NOTE ...as it matches this but it has different indentation
+
+fn bar() {
+ let mut i = 0;
+ while (i < 1000) {}
+}
+
+fn main() {}
+//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/issues/issue-2354.stderr b/src/test/ui/parser/issues/issue-2354.stderr
new file mode 100644
index 000000000..b89ed3958
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-2354.stderr
@@ -0,0 +1,16 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-2354.rs:15:52
+ |
+LL | fn foo() {
+ | - unclosed delimiter
+LL | match Some(10) {
+ | - this delimiter might not be properly closed...
+...
+LL | }
+ | - ...as it matches this but it has different indentation
+...
+LL |
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-23620-invalid-escapes.rs b/src/test/ui/parser/issues/issue-23620-invalid-escapes.rs
new file mode 100644
index 000000000..c1355f0d6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-23620-invalid-escapes.rs
@@ -0,0 +1,34 @@
+fn main() {
+ let _ = b"\u{a66e}";
+ //~^ ERROR unicode escape in byte string
+
+ let _ = b'\u{a66e}';
+ //~^ ERROR unicode escape in byte string
+
+ let _ = b'\u';
+ //~^ ERROR incorrect unicode escape sequence
+
+ let _ = b'\x5';
+ //~^ ERROR numeric character escape is too short
+
+ let _ = b'\xxy';
+ //~^ ERROR invalid character in numeric character escape: `x`
+
+ let _ = '\x5';
+ //~^ ERROR numeric character escape is too short
+
+ let _ = '\xxy';
+ //~^ ERROR invalid character in numeric character escape: `x`
+
+ let _ = b"\u{a4a4} \xf \u";
+ //~^ ERROR unicode escape in byte string
+ //~^^ ERROR invalid character in numeric character escape: ` `
+ //~^^^ ERROR incorrect unicode escape sequence
+
+ let _ = "\xf \u";
+ //~^ ERROR invalid character in numeric character escape: ` `
+ //~^^ ERROR incorrect unicode escape sequence
+
+ let _ = "\u8f";
+ //~^ ERROR incorrect unicode escape sequence
+}
diff --git a/src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr
new file mode 100644
index 000000000..88d97c795
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-23620-invalid-escapes.stderr
@@ -0,0 +1,94 @@
+error: unicode escape in byte string
+ --> $DIR/issue-23620-invalid-escapes.rs:2:15
+ |
+LL | let _ = b"\u{a66e}";
+ | ^^^^^^^^ unicode escape in byte string
+ |
+ = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: unicode escape in byte string
+ --> $DIR/issue-23620-invalid-escapes.rs:5:15
+ |
+LL | let _ = b'\u{a66e}';
+ | ^^^^^^^^ unicode escape in byte string
+ |
+ = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: incorrect unicode escape sequence
+ --> $DIR/issue-23620-invalid-escapes.rs:8:15
+ |
+LL | let _ = b'\u';
+ | ^^ incorrect unicode escape sequence
+ |
+ = help: format of unicode escape sequences is `\u{...}`
+
+error: numeric character escape is too short
+ --> $DIR/issue-23620-invalid-escapes.rs:11:15
+ |
+LL | let _ = b'\x5';
+ | ^^^
+
+error: invalid character in numeric character escape: `x`
+ --> $DIR/issue-23620-invalid-escapes.rs:14:17
+ |
+LL | let _ = b'\xxy';
+ | ^ invalid character in numeric character escape
+
+error: numeric character escape is too short
+ --> $DIR/issue-23620-invalid-escapes.rs:17:14
+ |
+LL | let _ = '\x5';
+ | ^^^
+
+error: invalid character in numeric character escape: `x`
+ --> $DIR/issue-23620-invalid-escapes.rs:20:16
+ |
+LL | let _ = '\xxy';
+ | ^ invalid character in numeric character escape
+
+error: unicode escape in byte string
+ --> $DIR/issue-23620-invalid-escapes.rs:23:15
+ |
+LL | let _ = b"\u{a4a4} \xf \u";
+ | ^^^^^^^^ unicode escape in byte string
+ |
+ = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: invalid character in numeric character escape: ` `
+ --> $DIR/issue-23620-invalid-escapes.rs:23:27
+ |
+LL | let _ = b"\u{a4a4} \xf \u";
+ | ^ invalid character in numeric character escape
+
+error: incorrect unicode escape sequence
+ --> $DIR/issue-23620-invalid-escapes.rs:23:28
+ |
+LL | let _ = b"\u{a4a4} \xf \u";
+ | ^^ incorrect unicode escape sequence
+ |
+ = help: format of unicode escape sequences is `\u{...}`
+
+error: invalid character in numeric character escape: ` `
+ --> $DIR/issue-23620-invalid-escapes.rs:28:17
+ |
+LL | let _ = "\xf \u";
+ | ^ invalid character in numeric character escape
+
+error: incorrect unicode escape sequence
+ --> $DIR/issue-23620-invalid-escapes.rs:28:18
+ |
+LL | let _ = "\xf \u";
+ | ^^ incorrect unicode escape sequence
+ |
+ = help: format of unicode escape sequences is `\u{...}`
+
+error: incorrect unicode escape sequence
+ --> $DIR/issue-23620-invalid-escapes.rs:32:14
+ |
+LL | let _ = "\u8f";
+ | ^^^-
+ | |
+ | help: format of unicode escape sequences uses braces: `\u{8f}`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-24197.rs b/src/test/ui/parser/issues/issue-24197.rs
new file mode 100644
index 000000000..aaf513746
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-24197.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let buf[0] = 0; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+}
diff --git a/src/test/ui/parser/issues/issue-24197.stderr b/src/test/ui/parser/issues/issue-24197.stderr
new file mode 100644
index 000000000..fd7015ccd
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-24197.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+ --> $DIR/issue-24197.rs:2:12
+ |
+LL | let buf[0] = 0;
+ | ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-24375.rs b/src/test/ui/parser/issues/issue-24375.rs
new file mode 100644
index 000000000..1d128d33e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-24375.rs
@@ -0,0 +1,9 @@
+static tmp : [&'static str; 2] = ["hello", "he"];
+
+fn main() {
+ let z = "hello";
+ match z {
+ tmp[0] => {} //~ ERROR expected one of `=>`, `@`, `if`, or `|`, found `[`
+ _ => {}
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-24375.stderr b/src/test/ui/parser/issues/issue-24375.stderr
new file mode 100644
index 000000000..7aed88768
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-24375.stderr
@@ -0,0 +1,8 @@
+error: expected one of `=>`, `@`, `if`, or `|`, found `[`
+ --> $DIR/issue-24375.rs:6:12
+ |
+LL | tmp[0] => {}
+ | ^ expected one of `=>`, `@`, `if`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-24780.rs b/src/test/ui/parser/issues/issue-24780.rs
new file mode 100644
index 000000000..017521f57
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-24780.rs
@@ -0,0 +1,9 @@
+// Verify that '>' is not both expected and found at the same time, as it used
+// to happen in #24780. For example, following should be an error:
+// expected one of ..., `>`, ... found `>`.
+
+fn foo() -> Vec<usize>> { //~ ERROR expected one of `!`, `+`, `::`, `where`, or `{`, found `>`
+ Vec::new()
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-24780.stderr b/src/test/ui/parser/issues/issue-24780.stderr
new file mode 100644
index 000000000..d9470191b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-24780.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `+`, `::`, `where`, or `{`, found `>`
+ --> $DIR/issue-24780.rs:5:23
+ |
+LL | fn foo() -> Vec<usize>> {
+ | ^ expected one of `!`, `+`, `::`, `where`, or `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-27255.rs b/src/test/ui/parser/issues/issue-27255.rs
new file mode 100644
index 000000000..d619688e1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-27255.rs
@@ -0,0 +1,10 @@
+trait A {}
+
+impl A .. {}
+//~^ ERROR missing `for` in a trait impl
+//~| ERROR `impl Trait for .. {}` is an obsolete syntax
+
+impl A usize {}
+//~^ ERROR missing `for` in a trait impl
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-27255.stderr b/src/test/ui/parser/issues/issue-27255.stderr
new file mode 100644
index 000000000..391a23556
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-27255.stderr
@@ -0,0 +1,22 @@
+error: missing `for` in a trait impl
+ --> $DIR/issue-27255.rs:3:7
+ |
+LL | impl A .. {}
+ | ^ help: add `for` here
+
+error: missing `for` in a trait impl
+ --> $DIR/issue-27255.rs:7:7
+ |
+LL | impl A usize {}
+ | ^^^^^^ help: add `for` here
+
+error: `impl Trait for .. {}` is an obsolete syntax
+ --> $DIR/issue-27255.rs:3:1
+ |
+LL | impl A .. {}
+ | ^^^^^^^^^^^^
+ |
+ = help: use `auto trait Trait {}` instead
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-30318.fixed b/src/test/ui/parser/issues/issue-30318.fixed
new file mode 100644
index 000000000..71fc82172
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-30318.fixed
@@ -0,0 +1,27 @@
+// run-rustfix
+#![allow(unused)]
+fn foo() { }
+
+/// Misplaced comment...
+//~^ ERROR expected outer doc comment
+fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
+
+#[test] //~ ERROR an inner attribute is not permitted in this context
+fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
+//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually
+
+/** Misplaced comment... */
+//~^ ERROR expected outer doc comment
+fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function
+
+fn main() { }
+
+// Misplaced comment...
+//~^ ERROR expected outer doc comment
+//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
+//~| NOTE other attributes here
+/* Misplaced comment... */
+//~^ ERROR expected outer doc comment
+//~| NOTE this doc comment doesn't document anything
+//~| ERROR expected item after doc comment
+//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
diff --git a/src/test/ui/parser/issues/issue-30318.rs b/src/test/ui/parser/issues/issue-30318.rs
new file mode 100644
index 000000000..465dca2ff
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-30318.rs
@@ -0,0 +1,27 @@
+// run-rustfix
+#![allow(unused)]
+fn foo() { }
+
+//! Misplaced comment...
+//~^ ERROR expected outer doc comment
+fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
+
+#![test] //~ ERROR an inner attribute is not permitted in this context
+fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
+//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually
+
+/*! Misplaced comment... */
+//~^ ERROR expected outer doc comment
+fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function
+
+fn main() { }
+
+//! Misplaced comment...
+//~^ ERROR expected outer doc comment
+//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
+//~| NOTE other attributes here
+/*! Misplaced comment... */
+//~^ ERROR expected outer doc comment
+//~| NOTE this doc comment doesn't document anything
+//~| ERROR expected item after doc comment
+//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
diff --git a/src/test/ui/parser/issues/issue-30318.stderr b/src/test/ui/parser/issues/issue-30318.stderr
new file mode 100644
index 000000000..c441a92ab
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-30318.stderr
@@ -0,0 +1,81 @@
+error[E0753]: expected outer doc comment
+ --> $DIR/issue-30318.rs:5:1
+ |
+LL | //! Misplaced comment...
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | fn bar() { }
+ | ------------ the inner doc comment doesn't annotate this function
+ |
+help: to annotate the function, change the doc comment from inner to outer style
+ |
+LL | /// Misplaced comment...
+ | ~
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/issue-30318.rs:9:1
+ |
+LL | #![test]
+ | ^^^^^^^^
+LL | fn baz() { }
+ | ------------ the inner attribute doesn't annotate this function
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the function, change the attribute from inner to outer style
+ |
+LL - #![test]
+LL + #[test]
+ |
+
+error[E0753]: expected outer doc comment
+ --> $DIR/issue-30318.rs:13:1
+ |
+LL | /*! Misplaced comment... */
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | fn bat() { }
+ | ------------ the inner doc comment doesn't annotate this function
+ |
+help: to annotate the function, change the doc comment from inner to outer style
+ |
+LL | /** Misplaced comment... */
+ | ~
+
+error[E0753]: expected outer doc comment
+ --> $DIR/issue-30318.rs:19:1
+ |
+LL | //! Misplaced comment...
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
+help: you might have meant to write a regular comment
+ |
+LL - //! Misplaced comment...
+LL + // Misplaced comment...
+ |
+
+error[E0753]: expected outer doc comment
+ --> $DIR/issue-30318.rs:23:1
+ |
+LL | /*! Misplaced comment... */
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
+help: you might have meant to write a regular comment
+ |
+LL - /*! Misplaced comment... */
+LL + /* Misplaced comment... */
+ |
+
+error: expected item after doc comment
+ --> $DIR/issue-30318.rs:23:1
+ |
+LL | //! Misplaced comment...
+ | ------------------------ other attributes here
+...
+LL | /*! Misplaced comment... */
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0753`.
diff --git a/src/test/ui/parser/issues/issue-3036.fixed b/src/test/ui/parser/issues/issue-3036.fixed
new file mode 100644
index 000000000..e5d5622e6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-3036.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+
+// Testing that semicolon tokens are printed correctly in errors
+
+fn main() {
+ let _x = 3; //~ ERROR: expected `;`
+}
diff --git a/src/test/ui/parser/issues/issue-3036.rs b/src/test/ui/parser/issues/issue-3036.rs
new file mode 100644
index 000000000..2f76fb99b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-3036.rs
@@ -0,0 +1,7 @@
+// run-rustfix
+
+// Testing that semicolon tokens are printed correctly in errors
+
+fn main() {
+ let _x = 3 //~ ERROR: expected `;`
+}
diff --git a/src/test/ui/parser/issues/issue-3036.stderr b/src/test/ui/parser/issues/issue-3036.stderr
new file mode 100644
index 000000000..e02223931
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-3036.stderr
@@ -0,0 +1,10 @@
+error: expected `;`, found `}`
+ --> $DIR/issue-3036.rs:6:15
+ |
+LL | let _x = 3
+ | ^ help: add `;` here
+LL | }
+ | - unexpected token
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-31804.rs b/src/test/ui/parser/issues/issue-31804.rs
new file mode 100644
index 000000000..d056b77cf
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-31804.rs
@@ -0,0 +1,6 @@
+// Test that error recovery in the parser to an EOF does not give an infinite
+// spew of errors.
+
+fn main() {
+ let
+} //~ ERROR expected pattern, found `}`
diff --git a/src/test/ui/parser/issues/issue-31804.stderr b/src/test/ui/parser/issues/issue-31804.stderr
new file mode 100644
index 000000000..76e68b0b3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-31804.stderr
@@ -0,0 +1,8 @@
+error: expected pattern, found `}`
+ --> $DIR/issue-31804.rs:6:1
+ |
+LL | }
+ | ^ expected pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-32214.rs b/src/test/ui/parser/issues/issue-32214.rs
new file mode 100644
index 000000000..1379eeb58
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32214.rs
@@ -0,0 +1,6 @@
+trait Trait<T> { type Item; }
+
+pub fn test<W, I: Trait<Item=(), W> >() {}
+//~^ ERROR generic arguments must come before the first constraint
+
+fn main() { }
diff --git a/src/test/ui/parser/issues/issue-32214.stderr b/src/test/ui/parser/issues/issue-32214.stderr
new file mode 100644
index 000000000..d0a9b5299
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32214.stderr
@@ -0,0 +1,15 @@
+error: generic arguments must come before the first constraint
+ --> $DIR/issue-32214.rs:3:34
+ |
+LL | pub fn test<W, I: Trait<Item=(), W> >() {}
+ | ------- ^ generic argument
+ | |
+ | constraint
+ |
+help: move the constraint after the generic argument
+ |
+LL | pub fn test<W, I: Trait<W, Item = ()> >() {}
+ | ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-32446.rs b/src/test/ui/parser/issues/issue-32446.rs
new file mode 100644
index 000000000..53e519a72
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32446.rs
@@ -0,0 +1,4 @@
+fn main() {}
+
+// This used to end up in an infite loop trying to bump past EOF.
+trait T { ... } //~ ERROR
diff --git a/src/test/ui/parser/issues/issue-32446.stderr b/src/test/ui/parser/issues/issue-32446.stderr
new file mode 100644
index 000000000..7515369aa
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32446.stderr
@@ -0,0 +1,11 @@
+error: non-item in item list
+ --> $DIR/issue-32446.rs:4:11
+ |
+LL | trait T { ... }
+ | - ^^^ - item list ends here
+ | | |
+ | | non-item starts here
+ | item list starts here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-32501.rs b/src/test/ui/parser/issues/issue-32501.rs
new file mode 100644
index 000000000..500242030
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32501.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let a = 0;
+ let _b = 0;
+ let _ = 0;
+ let mut b = 0;
+ let mut _b = 0;
+ let mut _ = 0;
+ //~^ ERROR `mut` must be followed by a named binding
+}
diff --git a/src/test/ui/parser/issues/issue-32501.stderr b/src/test/ui/parser/issues/issue-32501.stderr
new file mode 100644
index 000000000..d53302449
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32501.stderr
@@ -0,0 +1,10 @@
+error: `mut` must be followed by a named binding
+ --> $DIR/issue-32501.rs:7:9
+ |
+LL | let mut _ = 0;
+ | ^^^^^ help: remove the `mut` prefix: `_`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-32505.rs b/src/test/ui/parser/issues/issue-32505.rs
new file mode 100644
index 000000000..f31c00e5c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32505.rs
@@ -0,0 +1,5 @@
+pub fn test() {
+ foo(|_|) //~ ERROR expected expression, found `)`
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/issues/issue-32505.stderr b/src/test/ui/parser/issues/issue-32505.stderr
new file mode 100644
index 000000000..cdd779a93
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-32505.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `)`
+ --> $DIR/issue-32505.rs:2:12
+ |
+LL | foo(|_|)
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-33262.rs b/src/test/ui/parser/issues/issue-33262.rs
new file mode 100644
index 000000000..3a612f95c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33262.rs
@@ -0,0 +1,6 @@
+// Issue #33262
+
+pub fn main() {
+ for i in 0..a as { }
+ //~^ ERROR expected type, found `{`
+}
diff --git a/src/test/ui/parser/issues/issue-33262.stderr b/src/test/ui/parser/issues/issue-33262.stderr
new file mode 100644
index 000000000..2aff32839
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33262.stderr
@@ -0,0 +1,8 @@
+error: expected type, found `{`
+ --> $DIR/issue-33262.rs:4:22
+ |
+LL | for i in 0..a as { }
+ | ^ expected type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-33413.rs b/src/test/ui/parser/issues/issue-33413.rs
new file mode 100644
index 000000000..7291732ce
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33413.rs
@@ -0,0 +1,9 @@
+struct S;
+
+impl S {
+ fn f(*, a: u8) -> u8 {}
+ //~^ ERROR expected parameter name, found `*`
+ //~| ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-33413.stderr b/src/test/ui/parser/issues/issue-33413.stderr
new file mode 100644
index 000000000..b7250f3b0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33413.stderr
@@ -0,0 +1,22 @@
+error: expected parameter name, found `*`
+ --> $DIR/issue-33413.rs:4:10
+ |
+LL | fn f(*, a: u8) -> u8 {}
+ | ^ expected parameter name
+
+error[E0308]: mismatched types
+ --> $DIR/issue-33413.rs:4:23
+ |
+LL | fn f(*, a: u8) -> u8 {}
+ | - ^^ expected `u8`, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+ |
+help: consider returning the local binding `a`
+ |
+LL | fn f(*, a: u8) -> u8 { a }
+ | +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issues/issue-33418.fixed b/src/test/ui/parser/issues/issue-33418.fixed
new file mode 100644
index 000000000..ed885ae14
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33418.fixed
@@ -0,0 +1,19 @@
+// run-rustfix
+
+trait Tr {}
+//~^ ERROR negative bounds are not supported
+trait Tr2: SuperA {}
+//~^ ERROR negative bounds are not supported
+trait Tr3: SuperB {}
+//~^ ERROR negative bounds are not supported
+trait Tr4: SuperB + SuperD {}
+//~^ ERROR negative bounds are not supported
+trait Tr5 {}
+//~^ ERROR negative bounds are not supported
+
+trait SuperA {}
+trait SuperB {}
+trait SuperC {}
+trait SuperD {}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-33418.rs b/src/test/ui/parser/issues/issue-33418.rs
new file mode 100644
index 000000000..9934284ab
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33418.rs
@@ -0,0 +1,21 @@
+// run-rustfix
+
+trait Tr: !SuperA {}
+//~^ ERROR negative bounds are not supported
+trait Tr2: SuperA + !SuperB {}
+//~^ ERROR negative bounds are not supported
+trait Tr3: !SuperA + SuperB {}
+//~^ ERROR negative bounds are not supported
+trait Tr4: !SuperA + SuperB
+ + !SuperC + SuperD {}
+//~^ ERROR negative bounds are not supported
+trait Tr5: !SuperA
+ + !SuperB {}
+//~^ ERROR negative bounds are not supported
+
+trait SuperA {}
+trait SuperB {}
+trait SuperC {}
+trait SuperD {}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-33418.stderr b/src/test/ui/parser/issues/issue-33418.stderr
new file mode 100644
index 000000000..9a8733e89
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33418.stderr
@@ -0,0 +1,36 @@
+error: negative bounds are not supported
+ --> $DIR/issue-33418.rs:3:9
+ |
+LL | trait Tr: !SuperA {}
+ | ^^^^^^^^^ negative bounds are not supported
+
+error: negative bounds are not supported
+ --> $DIR/issue-33418.rs:5:19
+ |
+LL | trait Tr2: SuperA + !SuperB {}
+ | ^^^^^^^^^ negative bounds are not supported
+
+error: negative bounds are not supported
+ --> $DIR/issue-33418.rs:7:10
+ |
+LL | trait Tr3: !SuperA + SuperB {}
+ | ^^^^^^^^^ negative bounds are not supported
+
+error: negative bounds are not supported
+ --> $DIR/issue-33418.rs:9:10
+ |
+LL | trait Tr4: !SuperA + SuperB
+ | ^^^^^^^^^
+LL | + !SuperC + SuperD {}
+ | ^^^^^^^^^ negative bounds are not supported
+
+error: negative bounds are not supported
+ --> $DIR/issue-33418.rs:12:10
+ |
+LL | trait Tr5: !SuperA
+ | ^^^^^^^^^
+LL | + !SuperB {}
+ | ^^^^^^^^^ negative bounds are not supported
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-33455.rs b/src/test/ui/parser/issues/issue-33455.rs
new file mode 100644
index 000000000..6dff63f5c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33455.rs
@@ -0,0 +1 @@
+use foo.bar; //~ ERROR expected one of `::`, `;`, or `as`, found `.`
diff --git a/src/test/ui/parser/issues/issue-33455.stderr b/src/test/ui/parser/issues/issue-33455.stderr
new file mode 100644
index 000000000..c535ef23b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-33455.stderr
@@ -0,0 +1,8 @@
+error: expected one of `::`, `;`, or `as`, found `.`
+ --> $DIR/issue-33455.rs:1:8
+ |
+LL | use foo.bar;
+ | ^ expected one of `::`, `;`, or `as`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-34222-1.rs b/src/test/ui/parser/issues/issue-34222-1.rs
new file mode 100644
index 000000000..d36dddc97
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-34222-1.rs
@@ -0,0 +1,3 @@
+fn main() {
+ /// comment //~ ERROR found a documentation comment that doesn't document anything
+}
diff --git a/src/test/ui/parser/issues/issue-34222-1.stderr b/src/test/ui/parser/issues/issue-34222-1.stderr
new file mode 100644
index 000000000..0799656b0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-34222-1.stderr
@@ -0,0 +1,11 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/issue-34222-1.rs:2:5
+ |
+LL | /// comment
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/issues/issue-34255-1.rs b/src/test/ui/parser/issues/issue-34255-1.rs
new file mode 100644
index 000000000..c70cd8b50
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-34255-1.rs
@@ -0,0 +1,10 @@
+enum Test {
+ Drill {
+ field: i32,
+ }
+}
+
+fn main() {
+ Test::Drill(field: 42);
+ //~^ ERROR invalid `struct` delimiters or `fn` call arguments
+}
diff --git a/src/test/ui/parser/issues/issue-34255-1.stderr b/src/test/ui/parser/issues/issue-34255-1.stderr
new file mode 100644
index 000000000..0e2b0d62e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-34255-1.stderr
@@ -0,0 +1,18 @@
+error: invalid `struct` delimiters or `fn` call arguments
+ --> $DIR/issue-34255-1.rs:8:5
+ |
+LL | Test::Drill(field: 42);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: if `Test::Drill` is a struct, use braces as delimiters
+ |
+LL | Test::Drill { field: 42 };
+ | ~ ~
+help: if `Test::Drill` is a function, use the arguments directly
+ |
+LL - Test::Drill(field: 42);
+LL + Test::Drill(42);
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs
new file mode 100644
index 000000000..7bd4b3a16
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.rs
@@ -0,0 +1,171 @@
+// edition:2018
+#![crate_type = "lib"]
+#![feature(type_ascription)]
+use std::future::Future;
+use std::pin::Pin;
+
+// This tests the parser for "x as Y[z]". It errors, but we want to give useful
+// errors and parse such that further code gives useful errors.
+pub fn index_after_as_cast() {
+ vec![1, 2, 3] as Vec<i32>[0];
+ //~^ ERROR: cast cannot be followed by indexing
+ vec![1, 2, 3]: Vec<i32>[0];
+ //~^ ERROR: type ascription cannot be followed by indexing
+}
+
+pub fn index_after_cast_to_index() {
+ (&[0]) as &[i32][0];
+ //~^ ERROR: cast cannot be followed by indexing
+ (&[0i32]): &[i32; 1][0];
+ //~^ ERROR: type ascription cannot be followed by indexing
+}
+
+pub fn cast_after_cast() {
+ if 5u64 as i32 as u16 == 0u16 {
+
+ }
+ if 5u64: u64: u64 == 0u64 {
+
+ }
+ let _ = 5u64: u64: u64 as u8 as i8 == 9i8;
+ let _ = 0i32: i32: i32;
+ let _ = 0 as i32: i32;
+ let _ = 0i32: i32 as i32;
+ let _ = 0 as i32 as i32;
+ let _ = 0i32: i32: i32 as u32 as i32;
+}
+
+pub fn cast_cast_method_call() {
+ let _ = 0i32: i32: i32.count_ones();
+ //~^ ERROR: type ascription cannot be followed by a method call
+ let _ = 0 as i32: i32.count_ones();
+ //~^ ERROR: type ascription cannot be followed by a method call
+ let _ = 0i32: i32 as i32.count_ones();
+ //~^ ERROR: cast cannot be followed by a method call
+ let _ = 0 as i32 as i32.count_ones();
+ //~^ ERROR: cast cannot be followed by a method call
+ let _ = 0i32: i32: i32 as u32 as i32.count_ones();
+ //~^ ERROR: cast cannot be followed by a method call
+ let _ = 0i32: i32.count_ones(): u32;
+ //~^ ERROR: type ascription cannot be followed by a method call
+ let _ = 0 as i32.count_ones(): u32;
+ //~^ ERROR: cast cannot be followed by a method call
+ let _ = 0i32: i32.count_ones() as u32;
+ //~^ ERROR: type ascription cannot be followed by a method call
+ let _ = 0 as i32.count_ones() as u32;
+ //~^ ERROR: cast cannot be followed by a method call
+ let _ = 0i32: i32: i32.count_ones() as u32 as i32;
+ //~^ ERROR: type ascription cannot be followed by a method call
+}
+
+pub fn multiline_error() {
+ let _ = 0
+ as i32
+ .count_ones();
+ //~^^^ ERROR: cast cannot be followed by a method call
+}
+
+// this tests that the precedence for `!x as Y.Z` is still what we expect
+pub fn precedence() {
+ let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0];
+ //~^ ERROR: cast cannot be followed by indexing
+}
+
+pub fn method_calls() {
+ 0 as i32.max(0);
+ //~^ ERROR: cast cannot be followed by a method call
+ 0: i32.max(0);
+ //~^ ERROR: type ascription cannot be followed by a method call
+}
+
+pub fn complex() {
+ let _ = format!(
+ "{} and {}",
+ if true { 33 } else { 44 } as i32.max(0),
+ //~^ ERROR: cast cannot be followed by a method call
+ if true { 33 } else { 44 }: i32.max(0)
+ //~^ ERROR: type ascription cannot be followed by a method call
+ );
+}
+
+pub fn in_condition() {
+ if 5u64 as i32.max(0) == 0 {
+ //~^ ERROR: cast cannot be followed by a method call
+ }
+ if 5u64: u64.max(0) == 0 {
+ //~^ ERROR: type ascription cannot be followed by a method call
+ }
+}
+
+pub fn inside_block() {
+ let _ = if true {
+ 5u64 as u32.max(0) == 0
+ //~^ ERROR: cast cannot be followed by a method call
+ } else { false };
+ let _ = if true {
+ 5u64: u64.max(0) == 0
+ //~^ ERROR: type ascription cannot be followed by a method call
+ } else { false };
+}
+
+static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
+//~^ ERROR: cast cannot be followed by indexing
+
+static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
+//~^ ERROR: type ascription cannot be followed by indexing
+
+
+pub fn cast_then_try() -> Result<u64,u64> {
+ Err(0u64) as Result<u64,u64>?;
+ //~^ ERROR: cast cannot be followed by `?`
+ Err(0u64): Result<u64,u64>?;
+ //~^ ERROR: type ascription cannot be followed by `?`
+ Ok(1)
+}
+
+
+pub fn cast_then_call() {
+ type F = fn(u8);
+ // type ascription won't actually do [unique drop fn type] -> fn(u8) casts.
+ let drop_ptr = drop as fn(u8);
+ drop as F();
+ //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214]
+ drop_ptr: F();
+ //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214]
+}
+
+pub fn cast_to_fn_should_work() {
+ let drop_ptr = drop as fn(u8);
+ drop as fn(u8);
+ drop_ptr: fn(u8);
+}
+
+pub fn parens_after_cast_error() {
+ let drop_ptr = drop as fn(u8);
+ drop as fn(u8)(0);
+ //~^ ERROR: cast cannot be followed by a function call
+ drop_ptr: fn(u8)(0);
+ //~^ ERROR: type ascription cannot be followed by a function call
+}
+
+pub async fn cast_then_await() {
+ Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await;
+ //~^ ERROR: cast cannot be followed by `.await`
+
+ Box::pin(noop()): Pin<Box<_>>.await;
+ //~^ ERROR: type ascription cannot be followed by `.await`
+}
+
+pub async fn noop() {}
+
+#[derive(Default)]
+pub struct Foo {
+ pub bar: u32,
+}
+
+pub fn struct_field() {
+ Foo::default() as Foo.bar;
+ //~^ ERROR: cannot be followed by a field access
+ Foo::default(): Foo.bar;
+ //~^ ERROR: type ascription cannot be followed by a field access
+}
diff --git a/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr
new file mode 100644
index 000000000..0c328bde2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr
@@ -0,0 +1,472 @@
+error: cast cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:10:5
+ |
+LL | vec![1, 2, 3] as Vec<i32>[0];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (vec![1, 2, 3] as Vec<i32>)[0];
+ | + +
+
+error: type ascription cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:12:5
+ |
+LL | vec![1, 2, 3]: Vec<i32>[0];
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (vec![1, 2, 3]: Vec<i32>)[0];
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - vec![1, 2, 3]: Vec<i32>[0];
+LL + vec![1, 2, 3][0];
+ |
+
+error: cast cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:17:5
+ |
+LL | (&[0]) as &[i32][0];
+ | ^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | ((&[0]) as &[i32])[0];
+ | + +
+
+error: type ascription cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:19:5
+ |
+LL | (&[0i32]): &[i32; 1][0];
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | ((&[0i32]): &[i32; 1])[0];
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - (&[0i32]): &[i32; 1][0];
+LL + (&[0i32])[0];
+ |
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:39:13
+ |
+LL | let _ = 0i32: i32: i32.count_ones();
+ | ^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0i32: i32: i32).count_ones();
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - let _ = 0i32: i32: i32.count_ones();
+LL + let _ = 0i32: i32.count_ones();
+ |
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:41:13
+ |
+LL | let _ = 0 as i32: i32.count_ones();
+ | ^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0 as i32: i32).count_ones();
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - let _ = 0 as i32: i32.count_ones();
+LL + let _ = 0 as i32.count_ones();
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:43:13
+ |
+LL | let _ = 0i32: i32 as i32.count_ones();
+ | ^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0i32: i32 as i32).count_ones();
+ | + +
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:45:13
+ |
+LL | let _ = 0 as i32 as i32.count_ones();
+ | ^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0 as i32 as i32).count_ones();
+ | + +
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:47:13
+ |
+LL | let _ = 0i32: i32: i32 as u32 as i32.count_ones();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0i32: i32: i32 as u32 as i32).count_ones();
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:49:13
+ |
+LL | let _ = 0i32: i32.count_ones(): u32;
+ | ^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0i32: i32).count_ones(): u32;
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - let _ = 0i32: i32.count_ones(): u32;
+LL + let _ = 0i32.count_ones(): u32;
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:51:13
+ |
+LL | let _ = 0 as i32.count_ones(): u32;
+ | ^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0 as i32).count_ones(): u32;
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:53:13
+ |
+LL | let _ = 0i32: i32.count_ones() as u32;
+ | ^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0i32: i32).count_ones() as u32;
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - let _ = 0i32: i32.count_ones() as u32;
+LL + let _ = 0i32.count_ones() as u32;
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:55:13
+ |
+LL | let _ = 0 as i32.count_ones() as u32;
+ | ^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0 as i32).count_ones() as u32;
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:57:13
+ |
+LL | let _ = 0i32: i32: i32.count_ones() as u32 as i32;
+ | ^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32;
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32;
+LL + let _ = 0i32: i32.count_ones() as u32 as i32;
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:62:13
+ |
+LL | let _ = 0
+ | _____________^
+LL | | as i32
+ | |______________^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL ~ let _ = (0
+LL ~ as i32)
+ |
+
+error: cast cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:70:18
+ |
+LL | let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | let x: i32 = (&vec![1, 2, 3] as &Vec<i32>)[0];
+ | + +
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:75:5
+ |
+LL | 0 as i32.max(0);
+ | ^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (0 as i32).max(0);
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:77:5
+ |
+LL | 0: i32.max(0);
+ | ^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (0: i32).max(0);
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - 0: i32.max(0);
+LL + 0.max(0);
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:92:8
+ |
+LL | if 5u64 as i32.max(0) == 0 {
+ | ^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | if (5u64 as i32).max(0) == 0 {
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:95:8
+ |
+LL | if 5u64: u64.max(0) == 0 {
+ | ^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | if (5u64: u64).max(0) == 0 {
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - if 5u64: u64.max(0) == 0 {
+LL + if 5u64.max(0) == 0 {
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:102:9
+ |
+LL | 5u64 as u32.max(0) == 0
+ | ^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (5u64 as u32).max(0) == 0
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:106:9
+ |
+LL | 5u64: u64.max(0) == 0
+ | ^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (5u64: u64).max(0) == 0
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - 5u64: u64.max(0) == 0
+LL + 5u64.max(0) == 0
+ |
+
+error: cast cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:111:24
+ |
+LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]);
+ | + +
+
+error: type ascription cannot be followed by indexing
+ --> $DIR/issue-35813-postfix-after-cast.rs:114:25
+ |
+LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]);
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
+LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]);
+ |
+
+error: cast cannot be followed by `?`
+ --> $DIR/issue-35813-postfix-after-cast.rs:119:5
+ |
+LL | Err(0u64) as Result<u64,u64>?;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (Err(0u64) as Result<u64,u64>)?;
+ | + +
+
+error: type ascription cannot be followed by `?`
+ --> $DIR/issue-35813-postfix-after-cast.rs:121:5
+ |
+LL | Err(0u64): Result<u64,u64>?;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (Err(0u64): Result<u64,u64>)?;
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - Err(0u64): Result<u64,u64>?;
+LL + Err(0u64)?;
+ |
+
+error: cast cannot be followed by a function call
+ --> $DIR/issue-35813-postfix-after-cast.rs:145:5
+ |
+LL | drop as fn(u8)(0);
+ | ^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (drop as fn(u8))(0);
+ | + +
+
+error: type ascription cannot be followed by a function call
+ --> $DIR/issue-35813-postfix-after-cast.rs:147:5
+ |
+LL | drop_ptr: fn(u8)(0);
+ | ^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (drop_ptr: fn(u8))(0);
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - drop_ptr: fn(u8)(0);
+LL + drop_ptr(0);
+ |
+
+error: cast cannot be followed by `.await`
+ --> $DIR/issue-35813-postfix-after-cast.rs:152:5
+ |
+LL | Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>).await;
+ | + +
+
+error: type ascription cannot be followed by `.await`
+ --> $DIR/issue-35813-postfix-after-cast.rs:155:5
+ |
+LL | Box::pin(noop()): Pin<Box<_>>.await;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (Box::pin(noop()): Pin<Box<_>>).await;
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - Box::pin(noop()): Pin<Box<_>>.await;
+LL + Box::pin(noop()).await;
+ |
+
+error: cast cannot be followed by a field access
+ --> $DIR/issue-35813-postfix-after-cast.rs:167:5
+ |
+LL | Foo::default() as Foo.bar;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (Foo::default() as Foo).bar;
+ | + +
+
+error: type ascription cannot be followed by a field access
+ --> $DIR/issue-35813-postfix-after-cast.rs:169:5
+ |
+LL | Foo::default(): Foo.bar;
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (Foo::default(): Foo).bar;
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - Foo::default(): Foo.bar;
+LL + Foo::default().bar;
+ |
+
+error: cast cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:84:9
+ |
+LL | if true { 33 } else { 44 } as i32.max(0),
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (if true { 33 } else { 44 } as i32).max(0),
+ | + +
+
+error: type ascription cannot be followed by a method call
+ --> $DIR/issue-35813-postfix-after-cast.rs:86:9
+ |
+LL | if true { 33 } else { 44 }: i32.max(0)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try surrounding the expression in parentheses
+ |
+LL | (if true { 33 } else { 44 }: i32).max(0)
+ | + +
+help: alternatively, remove the type ascription
+ |
+LL - if true { 33 } else { 44 }: i32.max(0)
+LL + if true { 33 } else { 44 }.max(0)
+ |
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/issue-35813-postfix-after-cast.rs:131:13
+ |
+LL | drop as F();
+ | ^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/issue-35813-postfix-after-cast.rs:133:15
+ |
+LL | drop_ptr: F();
+ | ^^^ only `Fn` traits may use parentheses
+
+error: aborting due to 36 previous errors
+
+For more information about this error, try `rustc --explain E0214`.
diff --git a/src/test/ui/parser/issues/issue-41155.rs b/src/test/ui/parser/issues/issue-41155.rs
new file mode 100644
index 000000000..5a7488e6f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-41155.rs
@@ -0,0 +1,7 @@
+struct S;
+
+impl S {
+ pub //~ ERROR visibility `pub` is not followed by an item
+} //~ ERROR non-item in item list
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-41155.stderr b/src/test/ui/parser/issues/issue-41155.stderr
new file mode 100644
index 000000000..8491afae2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-41155.stderr
@@ -0,0 +1,22 @@
+error: visibility `pub` is not followed by an item
+ --> $DIR/issue-41155.rs:4:5
+ |
+LL | pub
+ | ^^^ the visibility
+ |
+ = help: you likely meant to define an item, e.g., `pub fn foo() {}`
+
+error: non-item in item list
+ --> $DIR/issue-41155.rs:5:1
+ |
+LL | impl S {
+ | - item list starts here
+LL | pub
+LL | }
+ | ^
+ | |
+ | non-item starts here
+ | item list ends here
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-43196.rs b/src/test/ui/parser/issues/issue-43196.rs
new file mode 100644
index 000000000..0eefa01ce
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-43196.rs
@@ -0,0 +1,6 @@
+fn main() {
+ |
+}
+//~^ ERROR expected `|`, found `}`
+|
+//~^ ERROR expected item, found `|`
diff --git a/src/test/ui/parser/issues/issue-43196.stderr b/src/test/ui/parser/issues/issue-43196.stderr
new file mode 100644
index 000000000..4f7ed5cc6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-43196.stderr
@@ -0,0 +1,16 @@
+error: expected `|`, found `}`
+ --> $DIR/issue-43196.rs:3:1
+ |
+LL | |
+ | - expected `|`
+LL | }
+ | ^ unexpected token
+
+error: expected item, found `|`
+ --> $DIR/issue-43196.rs:5:1
+ |
+LL | |
+ | ^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-43692.rs b/src/test/ui/parser/issues/issue-43692.rs
new file mode 100644
index 000000000..baf8bafb8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-43692.rs
@@ -0,0 +1,3 @@
+fn main() {
+ '\u{_10FFFF}'; //~ ERROR invalid start of unicode escape
+}
diff --git a/src/test/ui/parser/issues/issue-43692.stderr b/src/test/ui/parser/issues/issue-43692.stderr
new file mode 100644
index 000000000..baf998035
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-43692.stderr
@@ -0,0 +1,8 @@
+error: invalid start of unicode escape: `_`
+ --> $DIR/issue-43692.rs:2:9
+ |
+LL | '\u{_10FFFF}';
+ | ^ invalid start of unicode escape
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-44021.rs b/src/test/ui/parser/issues/issue-44021.rs
new file mode 100644
index 000000000..0b9558cc9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-44021.rs
@@ -0,0 +1,6 @@
+struct MyStruct;
+impl MyStruct {
+ fn f() {|x, y} //~ ERROR expected one of `:`, `@`, or `|`, found `}`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-44021.stderr b/src/test/ui/parser/issues/issue-44021.stderr
new file mode 100644
index 000000000..b888cd989
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-44021.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `@`, or `|`, found `}`
+ --> $DIR/issue-44021.rs:3:18
+ |
+LL | fn f() {|x, y}
+ | ^ expected one of `:`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-44406.rs b/src/test/ui/parser/issues/issue-44406.rs
new file mode 100644
index 000000000..a5b7e83a0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-44406.rs
@@ -0,0 +1,10 @@
+macro_rules! foo {
+ ($rest: tt) => {
+ bar(baz: $rest) //~ ERROR invalid `struct` delimiters or `fn` call arguments
+ }
+}
+
+fn main() {
+ foo!(true);
+ //~^ ERROR expected identifier, found keyword
+}
diff --git a/src/test/ui/parser/issues/issue-44406.stderr b/src/test/ui/parser/issues/issue-44406.stderr
new file mode 100644
index 000000000..1f0c1ea4c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-44406.stderr
@@ -0,0 +1,33 @@
+error: expected identifier, found keyword `true`
+ --> $DIR/issue-44406.rs:8:10
+ |
+LL | foo!(true);
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `true` to use it as an identifier
+ |
+LL | foo!(r#true);
+ | ++
+
+error: invalid `struct` delimiters or `fn` call arguments
+ --> $DIR/issue-44406.rs:3:9
+ |
+LL | bar(baz: $rest)
+ | ^^^^^^^^^^^^^^^
+...
+LL | foo!(true);
+ | ---------- in this macro invocation
+ |
+ = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: if `bar` is a struct, use braces as delimiters
+ |
+LL | bar { }
+ | ~
+help: if `bar` is a function, use the arguments directly
+ |
+LL - bar(baz: $rest)
+LL + bar(: $rest)
+ |
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-45296.rs b/src/test/ui/parser/issues/issue-45296.rs
new file mode 100644
index 000000000..d3a97e89f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-45296.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let unused = ();
+
+ #![allow(unused_variables)] //~ ERROR not permitted in this context
+ fn foo() {}
+}
diff --git a/src/test/ui/parser/issues/issue-45296.stderr b/src/test/ui/parser/issues/issue-45296.stderr
new file mode 100644
index 000000000..081a72054
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-45296.stderr
@@ -0,0 +1,17 @@
+error: an inner attribute is not permitted in this context
+ --> $DIR/issue-45296.rs:4:5
+ |
+LL | #![allow(unused_variables)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn foo() {}
+ | ----------- the inner attribute doesn't annotate this function
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the function, change the attribute from inner to outer style
+ |
+LL - #![allow(unused_variables)]
+LL + #[allow(unused_variables)]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-46186.fixed b/src/test/ui/parser/issues/issue-46186.fixed
new file mode 100644
index 000000000..2cb5a4996
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-46186.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub struct Struct {
+ pub a: usize,
+}
+//~^ ERROR expected item, found `;`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-46186.rs b/src/test/ui/parser/issues/issue-46186.rs
new file mode 100644
index 000000000..84cad38c5
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-46186.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub struct Struct {
+ pub a: usize,
+};
+//~^ ERROR expected item, found `;`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-46186.stderr b/src/test/ui/parser/issues/issue-46186.stderr
new file mode 100644
index 000000000..0766c8a33
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-46186.stderr
@@ -0,0 +1,10 @@
+error: expected item, found `;`
+ --> $DIR/issue-46186.rs:5:2
+ |
+LL | };
+ | ^ help: remove this semicolon
+ |
+ = help: braced struct declarations are not followed by a semicolon
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs
new file mode 100644
index 000000000..48a679b2d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs
@@ -0,0 +1,44 @@
+fn main() {}
+
+macro_rules! expand_to_enum {
+ () => {
+ enum BadE {}
+ //~^ ERROR enum is not supported in `trait`s or `impl`s
+ //~| ERROR enum is not supported in `trait`s or `impl`s
+ //~| ERROR enum is not supported in `extern` blocks
+ };
+}
+
+macro_rules! mac_impl {
+ ($($i:item)*) => {
+ struct S;
+ impl S { $($i)* }
+ }
+}
+
+mac_impl! {
+ struct BadS; //~ ERROR struct is not supported in `trait`s or `impl`s
+ expand_to_enum!();
+}
+
+macro_rules! mac_trait {
+ ($($i:item)*) => {
+ trait T { $($i)* }
+ }
+}
+
+mac_trait! {
+ struct BadS; //~ ERROR struct is not supported in `trait`s or `impl`s
+ expand_to_enum!();
+}
+
+macro_rules! mac_extern {
+ ($($i:item)*) => {
+ extern "C" { $($i)* }
+ }
+}
+
+mac_extern! {
+ struct BadS; //~ ERROR struct is not supported in `extern` blocks
+ expand_to_enum!();
+}
diff --git a/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr
new file mode 100644
index 000000000..fdef8ff6d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr
@@ -0,0 +1,62 @@
+error: struct is not supported in `trait`s or `impl`s
+ --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:20:5
+ |
+LL | struct BadS;
+ | ^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: enum is not supported in `trait`s or `impl`s
+ --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9
+ |
+LL | enum BadE {}
+ | ^^^^^^^^^
+...
+LL | expand_to_enum!();
+ | ----------------- in this macro invocation
+ |
+ = help: consider moving the enum out to a nearby module scope
+ = note: this error originates in the macro `expand_to_enum` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: struct is not supported in `trait`s or `impl`s
+ --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:31:5
+ |
+LL | struct BadS;
+ | ^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: enum is not supported in `trait`s or `impl`s
+ --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9
+ |
+LL | enum BadE {}
+ | ^^^^^^^^^
+...
+LL | expand_to_enum!();
+ | ----------------- in this macro invocation
+ |
+ = help: consider moving the enum out to a nearby module scope
+ = note: this error originates in the macro `expand_to_enum` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: struct is not supported in `extern` blocks
+ --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:42:5
+ |
+LL | struct BadS;
+ | ^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: enum is not supported in `extern` blocks
+ --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9
+ |
+LL | enum BadE {}
+ | ^^^^^^^^^
+...
+LL | expand_to_enum!();
+ | ----------------- in this macro invocation
+ |
+ = help: consider moving the enum out to a nearby module scope
+ = note: this error originates in the macro `expand_to_enum` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs
new file mode 100644
index 000000000..8592f8a72
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48137-macros-cannot-interpolate-impl-items.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+fn main() {}
+
+macro_rules! mac_impl {
+ ($i:item) => {
+ struct S;
+ impl S { $i }
+ }
+}
+
+mac_impl! {
+ fn foo() {}
+}
+
+macro_rules! mac_trait {
+ ($i:item) => {
+ trait T { $i }
+ }
+}
+
+mac_trait! {
+ fn foo() {}
+}
+
+macro_rules! mac_extern {
+ ($i:item) => {
+ extern "C" { $i }
+ }
+}
+
+mac_extern! {
+ fn foo();
+}
diff --git a/src/test/ui/parser/issues/issue-48508-aux.rs b/src/test/ui/parser/issues/issue-48508-aux.rs
new file mode 100644
index 000000000..ebdc70a04
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48508-aux.rs
@@ -0,0 +1,7 @@
+// run-pass
+// ignore-test Not a test. Used by issue-48508.rs
+
+pub fn other() -> f64 {
+ let µ = 1.0;
+ µ
+}
diff --git a/src/test/ui/parser/issues/issue-48508.rs b/src/test/ui/parser/issues/issue-48508.rs
new file mode 100644
index 000000000..37d04c5d6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48508.rs
@@ -0,0 +1,20 @@
+// run-pass
+// Regression test for issue #48508:
+//
+// Confusion between global and local file offsets caused incorrect handling of multibyte character
+// spans when compiling multiple files. One visible effect was an ICE generating debug information
+// when a multibyte character is at the end of a scope. The problematic code is actually in
+// issue-48508-aux.rs
+
+// compile-flags:-g
+// ignore-pretty issue #37195
+// ignore-asmjs wasm2js does not support source maps yet
+
+#![allow(uncommon_codepoints)]
+
+#[path = "issue-48508-aux.rs"]
+mod other_file;
+
+fn main() {
+ other_file::other();
+}
diff --git a/src/test/ui/parser/issues/issue-48636.fixed b/src/test/ui/parser/issues/issue-48636.fixed
new file mode 100644
index 000000000..87c19a32d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48636.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+struct S {
+ x: u8,
+ /// The ID of the parent core
+ y: u8,
+}
+//~^^^ ERROR found a documentation comment that doesn't document anything
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-48636.rs b/src/test/ui/parser/issues/issue-48636.rs
new file mode 100644
index 000000000..8610dc2f7
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48636.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+
+#![allow(dead_code)]
+
+struct S {
+ x: u8
+ /// The ID of the parent core
+ y: u8,
+}
+//~^^^ ERROR found a documentation comment that doesn't document anything
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-48636.stderr b/src/test/ui/parser/issues/issue-48636.stderr
new file mode 100644
index 000000000..462723d1d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-48636.stderr
@@ -0,0 +1,13 @@
+error[E0585]: found a documentation comment that doesn't document anything
+ --> $DIR/issue-48636.rs:7:5
+ |
+LL | x: u8
+ | - help: missing comma here: `,`
+LL | /// The ID of the parent core
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/parser/issues/issue-49040.rs b/src/test/ui/parser/issues/issue-49040.rs
new file mode 100644
index 000000000..b7a541dd6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-49040.rs
@@ -0,0 +1,3 @@
+#![allow(unused_variables)]; //~ ERROR expected item, found `;`
+//~^ ERROR `main` function
+fn foo() {}
diff --git a/src/test/ui/parser/issues/issue-49040.stderr b/src/test/ui/parser/issues/issue-49040.stderr
new file mode 100644
index 000000000..8af7838c7
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-49040.stderr
@@ -0,0 +1,15 @@
+error: expected item, found `;`
+ --> $DIR/issue-49040.rs:1:28
+ |
+LL | #![allow(unused_variables)];
+ | ^ help: remove this semicolon
+
+error[E0601]: `main` function not found in crate `issue_49040`
+ --> $DIR/issue-49040.rs:1:29
+ |
+LL | #![allow(unused_variables)];
+ | ^ consider adding a `main` function to `$DIR/issue-49040.rs`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/parser/issues/issue-51602.rs b/src/test/ui/parser/issues/issue-51602.rs
new file mode 100644
index 000000000..0e96ca914
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-51602.rs
@@ -0,0 +1,6 @@
+fn main(){
+ if i in 1..10 {
+//~^ ERROR expected `{`, found keyword `in`
+ break;
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-51602.stderr b/src/test/ui/parser/issues/issue-51602.stderr
new file mode 100644
index 000000000..4a5653fdb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-51602.stderr
@@ -0,0 +1,14 @@
+error: expected `{`, found keyword `in`
+ --> $DIR/issue-51602.rs:2:10
+ |
+LL | if i in 1..10 {
+ | ^^ expected `{`
+ |
+note: the `if` expression is missing a block after this condition
+ --> $DIR/issue-51602.rs:2:8
+ |
+LL | if i in 1..10 {
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-52496.rs b/src/test/ui/parser/issues/issue-52496.rs
new file mode 100644
index 000000000..05461f8b8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-52496.rs
@@ -0,0 +1,12 @@
+struct Foo { bar: f64, baz: i64, bat: i64 }
+
+fn main() {
+ let _ = Foo { bar: .5, baz: 42 };
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR missing field `bat` in initializer of `Foo`
+ let bar = 1.5f32;
+ let _ = Foo { bar.into(), bat: -1, . };
+ //~^ ERROR expected one of
+ //~| ERROR missing fields `bar` and `baz` in initializer of `Foo`
+ //~| ERROR expected identifier, found `.`
+}
diff --git a/src/test/ui/parser/issues/issue-52496.stderr b/src/test/ui/parser/issues/issue-52496.stderr
new file mode 100644
index 000000000..77335c64c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-52496.stderr
@@ -0,0 +1,38 @@
+error: float literals must have an integer part
+ --> $DIR/issue-52496.rs:4:24
+ |
+LL | let _ = Foo { bar: .5, baz: 42 };
+ | ^^ help: must have an integer part: `0.5`
+
+error: expected one of `,`, `:`, or `}`, found `.`
+ --> $DIR/issue-52496.rs:8:22
+ |
+LL | let _ = Foo { bar.into(), bat: -1, . };
+ | --- - ^ expected one of `,`, `:`, or `}`
+ | | |
+ | | help: try naming a field: `bar:`
+ | while parsing this struct
+
+error: expected identifier, found `.`
+ --> $DIR/issue-52496.rs:8:40
+ |
+LL | let _ = Foo { bar.into(), bat: -1, . };
+ | --- ^ expected identifier
+ | |
+ | while parsing this struct
+
+error[E0063]: missing field `bat` in initializer of `Foo`
+ --> $DIR/issue-52496.rs:4:13
+ |
+LL | let _ = Foo { bar: .5, baz: 42 };
+ | ^^^ missing `bat`
+
+error[E0063]: missing fields `bar` and `baz` in initializer of `Foo`
+ --> $DIR/issue-52496.rs:8:13
+ |
+LL | let _ = Foo { bar.into(), bat: -1, . };
+ | ^^^ missing `bar` and `baz`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/parser/issues/issue-54521-1.rs b/src/test/ui/parser/issues/issue-54521-1.rs
new file mode 100644
index 000000000..8a682ef0a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-1.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+// This test checks that the `remove extra angle brackets` error doesn't happen for some
+// potential edge-cases..
+
+struct X {
+ len: u32,
+}
+
+fn main() {
+ let x = X { len: 3 };
+
+ let _ = x.len > (3);
+
+ let _ = x.len >> (3);
+}
diff --git a/src/test/ui/parser/issues/issue-54521-2.fixed b/src/test/ui/parser/issues/issue-54521-2.fixed
new file mode 100644
index 000000000..a91c4fe43
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-2.fixed
@@ -0,0 +1,22 @@
+// run-rustfix
+
+// This test checks that the following error is emitted and the suggestion works:
+//
+// ```
+// let _ = Vec::<usize>>>::new();
+// ^^ help: remove extra angle brackets
+// ```
+
+fn main() {
+ let _ = Vec::<usize>::new();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = Vec::<usize>::new();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = Vec::<usize>::new();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = Vec::<usize>::new();
+ //~^ ERROR unmatched angle bracket
+}
diff --git a/src/test/ui/parser/issues/issue-54521-2.rs b/src/test/ui/parser/issues/issue-54521-2.rs
new file mode 100644
index 000000000..3639aac87
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-2.rs
@@ -0,0 +1,22 @@
+// run-rustfix
+
+// This test checks that the following error is emitted and the suggestion works:
+//
+// ```
+// let _ = Vec::<usize>>>::new();
+// ^^ help: remove extra angle brackets
+// ```
+
+fn main() {
+ let _ = Vec::<usize>>>>>::new();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = Vec::<usize>>>>::new();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = Vec::<usize>>>::new();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = Vec::<usize>>::new();
+ //~^ ERROR unmatched angle bracket
+}
diff --git a/src/test/ui/parser/issues/issue-54521-2.stderr b/src/test/ui/parser/issues/issue-54521-2.stderr
new file mode 100644
index 000000000..9556b83b7
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-2.stderr
@@ -0,0 +1,26 @@
+error: unmatched angle brackets
+ --> $DIR/issue-54521-2.rs:11:25
+ |
+LL | let _ = Vec::<usize>>>>>::new();
+ | ^^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-54521-2.rs:14:25
+ |
+LL | let _ = Vec::<usize>>>>::new();
+ | ^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-54521-2.rs:17:25
+ |
+LL | let _ = Vec::<usize>>>::new();
+ | ^^ help: remove extra angle brackets
+
+error: unmatched angle bracket
+ --> $DIR/issue-54521-2.rs:20:25
+ |
+LL | let _ = Vec::<usize>>::new();
+ | ^ help: remove extra angle bracket
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-54521-3.fixed b/src/test/ui/parser/issues/issue-54521-3.fixed
new file mode 100644
index 000000000..84ab6866c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-3.fixed
@@ -0,0 +1,22 @@
+// run-rustfix
+
+// This test checks that the following error is emitted and the suggestion works:
+//
+// ```
+// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
+// ^^ help: remove extra angle brackets
+// ```
+
+fn main() {
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+}
diff --git a/src/test/ui/parser/issues/issue-54521-3.rs b/src/test/ui/parser/issues/issue-54521-3.rs
new file mode 100644
index 000000000..f1d685041
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-3.rs
@@ -0,0 +1,22 @@
+// run-rustfix
+
+// This test checks that the following error is emitted and the suggestion works:
+//
+// ```
+// let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
+// ^^ help: remove extra angle brackets
+// ```
+
+fn main() {
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>();
+ //~^ ERROR unmatched angle bracket
+}
diff --git a/src/test/ui/parser/issues/issue-54521-3.stderr b/src/test/ui/parser/issues/issue-54521-3.stderr
new file mode 100644
index 000000000..0f23dd621
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-54521-3.stderr
@@ -0,0 +1,26 @@
+error: unmatched angle brackets
+ --> $DIR/issue-54521-3.rs:11:60
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>>();
+ | ^^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-54521-3.rs:14:60
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>();
+ | ^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-54521-3.rs:17:60
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
+ | ^^ help: remove extra angle brackets
+
+error: unmatched angle bracket
+ --> $DIR/issue-54521-3.rs:20:60
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>();
+ | ^ help: remove extra angle bracket
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-5544-a.rs b/src/test/ui/parser/issues/issue-5544-a.rs
new file mode 100644
index 000000000..3c239c73b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-5544-a.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let __isize = 340282366920938463463374607431768211456; // 2^128
+ //~^ ERROR integer literal is too large
+}
diff --git a/src/test/ui/parser/issues/issue-5544-a.stderr b/src/test/ui/parser/issues/issue-5544-a.stderr
new file mode 100644
index 000000000..de579c3c1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-5544-a.stderr
@@ -0,0 +1,8 @@
+error: integer literal is too large
+ --> $DIR/issue-5544-a.rs:2:19
+ |
+LL | let __isize = 340282366920938463463374607431768211456; // 2^128
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-5544-b.rs b/src/test/ui/parser/issues/issue-5544-b.rs
new file mode 100644
index 000000000..93f2ff271
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-5544-b.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff;
+ //~^ ERROR integer literal is too large
+}
diff --git a/src/test/ui/parser/issues/issue-5544-b.stderr b/src/test/ui/parser/issues/issue-5544-b.stderr
new file mode 100644
index 000000000..7df212ded
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-5544-b.stderr
@@ -0,0 +1,8 @@
+error: integer literal is too large
+ --> $DIR/issue-5544-b.rs:2:19
+ |
+LL | let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-56031.rs b/src/test/ui/parser/issues/issue-56031.rs
new file mode 100644
index 000000000..b68f56814
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-56031.rs
@@ -0,0 +1,6 @@
+struct T;
+
+impl for T {}
+//~^ ERROR missing trait in a trait impl
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-56031.stderr b/src/test/ui/parser/issues/issue-56031.stderr
new file mode 100644
index 000000000..2fa05dd2d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-56031.stderr
@@ -0,0 +1,18 @@
+error: missing trait in a trait impl
+ --> $DIR/issue-56031.rs:3:5
+ |
+LL | impl for T {}
+ | ^
+ |
+help: add a trait here
+ |
+LL | impl Trait for T {}
+ | +++++
+help: for an inherent impl, drop this `for`
+ |
+LL - impl for T {}
+LL + impl T {}
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-57198.rs b/src/test/ui/parser/issues/issue-57198.rs
new file mode 100644
index 000000000..714a46cbc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57198.rs
@@ -0,0 +1,8 @@
+mod m {
+ pub fn r#for() {}
+}
+
+fn main() {
+ m::for();
+ //~^ ERROR expected identifier, found keyword `for`
+}
diff --git a/src/test/ui/parser/issues/issue-57198.stderr b/src/test/ui/parser/issues/issue-57198.stderr
new file mode 100644
index 000000000..dd70b4022
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57198.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `for`
+ --> $DIR/issue-57198.rs:6:8
+ |
+LL | m::for();
+ | ^^^ expected identifier, found keyword
+ |
+help: escape `for` to use it as an identifier
+ |
+LL | m::r#for();
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-57684.fixed b/src/test/ui/parser/issues/issue-57684.fixed
new file mode 100644
index 000000000..4a432206d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57684.fixed
@@ -0,0 +1,37 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+// This test checks that the following error is emitted when a `=` character is used to initialize
+// a struct field when a `:` is expected.
+//
+// ```
+// error: struct fields are initialized with a colon
+// --> $DIR/issue-57684.rs:12:20
+// |
+// LL | let _ = X { f1 = 5 };
+// | ^ help: replace equals symbol with a colon: `:`
+// ```
+
+struct X {
+ f1: i32,
+}
+
+struct Y {
+ f1: i32,
+ f2: i32,
+ f3: i32,
+}
+
+fn main() {
+ let _ = X { f1: 5 };
+ //~^ ERROR expected `:`, found `=`
+
+ let f3 = 3;
+ let _ = Y {
+ f1: 5,
+ //~^ ERROR expected `:`, found `=`
+ f2: 4,
+ f3,
+ };
+}
diff --git a/src/test/ui/parser/issues/issue-57684.rs b/src/test/ui/parser/issues/issue-57684.rs
new file mode 100644
index 000000000..7a62785e3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57684.rs
@@ -0,0 +1,37 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+// This test checks that the following error is emitted when a `=` character is used to initialize
+// a struct field when a `:` is expected.
+//
+// ```
+// error: struct fields are initialized with a colon
+// --> $DIR/issue-57684.rs:12:20
+// |
+// LL | let _ = X { f1 = 5 };
+// | ^ help: replace equals symbol with a colon: `:`
+// ```
+
+struct X {
+ f1: i32,
+}
+
+struct Y {
+ f1: i32,
+ f2: i32,
+ f3: i32,
+}
+
+fn main() {
+ let _ = X { f1 = 5 };
+ //~^ ERROR expected `:`, found `=`
+
+ let f3 = 3;
+ let _ = Y {
+ f1 = 5,
+ //~^ ERROR expected `:`, found `=`
+ f2: 4,
+ f3,
+ };
+}
diff --git a/src/test/ui/parser/issues/issue-57684.stderr b/src/test/ui/parser/issues/issue-57684.stderr
new file mode 100644
index 000000000..514bbffde
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57684.stderr
@@ -0,0 +1,18 @@
+error: expected `:`, found `=`
+ --> $DIR/issue-57684.rs:27:20
+ |
+LL | let _ = X { f1 = 5 };
+ | -^
+ | |
+ | help: replace equals symbol with a colon: `:`
+
+error: expected `:`, found `=`
+ --> $DIR/issue-57684.rs:32:12
+ |
+LL | f1 = 5,
+ | -^
+ | |
+ | help: replace equals symbol with a colon: `:`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-57819.fixed b/src/test/ui/parser/issues/issue-57819.fixed
new file mode 100644
index 000000000..3fab21db2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57819.fixed
@@ -0,0 +1,47 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+// This test checks that the following error is emitted and the suggestion works:
+//
+// ```
+// let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>();
+// ^^ help: remove extra angle brackets
+// ```
+
+trait Foo {
+ type Output;
+}
+
+fn foo<T: Foo>() {
+ // More complex cases with more than one correct leading `<` character:
+
+ bar::<<T as Foo>::Output>();
+ //~^ ERROR unmatched angle bracket
+
+ bar::<<T as Foo>::Output>();
+ //~^ ERROR unmatched angle bracket
+
+ bar::<<T as Foo>::Output>();
+ //~^ ERROR unmatched angle bracket
+
+ bar::<<T as Foo>::Output>();
+}
+
+fn bar<T>() {}
+
+fn main() {
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+}
diff --git a/src/test/ui/parser/issues/issue-57819.rs b/src/test/ui/parser/issues/issue-57819.rs
new file mode 100644
index 000000000..5cafbf439
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57819.rs
@@ -0,0 +1,47 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+// This test checks that the following error is emitted and the suggestion works:
+//
+// ```
+// let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>();
+// ^^ help: remove extra angle brackets
+// ```
+
+trait Foo {
+ type Output;
+}
+
+fn foo<T: Foo>() {
+ // More complex cases with more than one correct leading `<` character:
+
+ bar::<<<<<T as Foo>::Output>();
+ //~^ ERROR unmatched angle bracket
+
+ bar::<<<<T as Foo>::Output>();
+ //~^ ERROR unmatched angle bracket
+
+ bar::<<<T as Foo>::Output>();
+ //~^ ERROR unmatched angle bracket
+
+ bar::<<T as Foo>::Output>();
+}
+
+fn bar<T>() {}
+
+fn main() {
+ let _ = vec![1, 2, 3].into_iter().collect::<<<<<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<<<<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<<Vec<usize>>();
+ //~^ ERROR unmatched angle bracket
+
+ let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>();
+}
diff --git a/src/test/ui/parser/issues/issue-57819.stderr b/src/test/ui/parser/issues/issue-57819.stderr
new file mode 100644
index 000000000..493e9835b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-57819.stderr
@@ -0,0 +1,44 @@
+error: unmatched angle brackets
+ --> $DIR/issue-57819.rs:19:10
+ |
+LL | bar::<<<<<T as Foo>::Output>();
+ | ^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-57819.rs:22:10
+ |
+LL | bar::<<<<T as Foo>::Output>();
+ | ^^ help: remove extra angle brackets
+
+error: unmatched angle bracket
+ --> $DIR/issue-57819.rs:25:10
+ |
+LL | bar::<<<T as Foo>::Output>();
+ | ^ help: remove extra angle bracket
+
+error: unmatched angle brackets
+ --> $DIR/issue-57819.rs:34:48
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<<<<<Vec<usize>>();
+ | ^^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-57819.rs:37:48
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<<<<Vec<usize>>();
+ | ^^^ help: remove extra angle brackets
+
+error: unmatched angle brackets
+ --> $DIR/issue-57819.rs:40:48
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<<<Vec<usize>>();
+ | ^^ help: remove extra angle brackets
+
+error: unmatched angle bracket
+ --> $DIR/issue-57819.rs:43:48
+ |
+LL | let _ = vec![1, 2, 3].into_iter().collect::<<Vec<usize>>();
+ | ^ help: remove extra angle bracket
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-5806.rs b/src/test/ui/parser/issues/issue-5806.rs
new file mode 100644
index 000000000..b694642a9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-5806.rs
@@ -0,0 +1,7 @@
+// normalize-stderr-test: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG ("
+// normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE"
+
+#[path = "../parser"]
+mod foo; //~ ERROR couldn't read
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-5806.stderr b/src/test/ui/parser/issues/issue-5806.stderr
new file mode 100644
index 000000000..bdb5c91ff
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-5806.stderr
@@ -0,0 +1,8 @@
+error: couldn't read $DIR/../parser: $ACCESS_DENIED_MSG (os error $ACCESS_DENIED_CODE)
+ --> $DIR/issue-5806.rs:5:1
+ |
+LL | mod foo;
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs
new file mode 100644
index 000000000..25699f9fe
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.rs
@@ -0,0 +1,4 @@
+// Fixed in #66054.
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 2 previous errors
+#[Ѕ \ No newline at end of file
diff --git a/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr
new file mode 100644
index 000000000..8a44ee761
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-58094-missing-right-square-bracket.stderr
@@ -0,0 +1,16 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-58094-missing-right-square-bracket.rs:4:4
+ |
+LL | #[Ѕ
+ | - ^
+ | |
+ | unclosed delimiter
+
+error: expected item after attributes
+ --> $DIR/issue-58094-missing-right-square-bracket.rs:4:1
+ |
+LL | #[Ѕ
+ | ^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-58856-1.rs b/src/test/ui/parser/issues/issue-58856-1.rs
new file mode 100644
index 000000000..ea80eb871
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-58856-1.rs
@@ -0,0 +1,8 @@
+impl A {
+ //~^ ERROR cannot find type `A` in this scope
+ fn b(self>
+ //~^ ERROR expected one of `)`, `,`, or `:`, found `>`
+ //~| ERROR expected one of `->`, `where`, or `{`, found `>`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-58856-1.stderr b/src/test/ui/parser/issues/issue-58856-1.stderr
new file mode 100644
index 000000000..96151f3fe
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-58856-1.stderr
@@ -0,0 +1,29 @@
+error: expected one of `)`, `,`, or `:`, found `>`
+ --> $DIR/issue-58856-1.rs:3:9
+ |
+LL | fn b(self>
+ | ^ ^ help: `)` may belong here
+ | |
+ | unclosed delimiter
+
+error: expected one of `->`, `where`, or `{`, found `>`
+ --> $DIR/issue-58856-1.rs:3:14
+ |
+LL | impl A {
+ | - while parsing this item list starting here
+LL |
+LL | fn b(self>
+ | ^ expected one of `->`, `where`, or `{`
+...
+LL | }
+ | - the item list ends here
+
+error[E0412]: cannot find type `A` in this scope
+ --> $DIR/issue-58856-1.rs:1:6
+ |
+LL | impl A {
+ | ^ not found in this scope
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/issues/issue-58856-2.rs b/src/test/ui/parser/issues/issue-58856-2.rs
new file mode 100644
index 000000000..9356d57b0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-58856-2.rs
@@ -0,0 +1,14 @@
+struct Empty;
+
+trait Howness {}
+
+impl Howness for () {
+ fn how_are_you(&self -> Empty {
+ //~^ ERROR expected one of `)` or `,`, found `->`
+ //~| ERROR method `how_are_you` is not a member of trait `Howness`
+ Empty
+ }
+}
+//~^ ERROR non-item in item list
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-58856-2.stderr b/src/test/ui/parser/issues/issue-58856-2.stderr
new file mode 100644
index 000000000..627dd3890
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-58856-2.stderr
@@ -0,0 +1,34 @@
+error: expected one of `)` or `,`, found `->`
+ --> $DIR/issue-58856-2.rs:6:19
+ |
+LL | fn how_are_you(&self -> Empty {
+ | ^ -^^
+ | | |
+ | | help: `)` may belong here
+ | unclosed delimiter
+
+error: non-item in item list
+ --> $DIR/issue-58856-2.rs:11:1
+ |
+LL | impl Howness for () {
+ | - item list starts here
+...
+LL | }
+ | ^
+ | |
+ | non-item starts here
+ | item list ends here
+
+error[E0407]: method `how_are_you` is not a member of trait `Howness`
+ --> $DIR/issue-58856-2.rs:6:5
+ |
+LL | / fn how_are_you(&self -> Empty {
+LL | |
+LL | |
+LL | | Empty
+LL | | }
+ | |_____^ not a member of trait `Howness`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0407`.
diff --git a/src/test/ui/parser/issues/issue-59418.rs b/src/test/ui/parser/issues/issue-59418.rs
new file mode 100644
index 000000000..0fa191d4a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-59418.rs
@@ -0,0 +1,18 @@
+struct X(i32,i32,i32);
+
+fn main() {
+ let a = X(1, 2, 3);
+ let b = a.1suffix;
+ //~^ ERROR suffixes on a tuple index are invalid
+ println!("{}", b);
+ let c = (1, 2, 3);
+ let d = c.1suffix;
+ //~^ ERROR suffixes on a tuple index are invalid
+ println!("{}", d);
+ let s = X { 0suffix: 0, 1: 1, 2: 2 };
+ //~^ ERROR suffixes on a tuple index are invalid
+ match s {
+ X { 0suffix: _, .. } => {}
+ //~^ ERROR suffixes on a tuple index are invalid
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-59418.stderr b/src/test/ui/parser/issues/issue-59418.stderr
new file mode 100644
index 000000000..347051e9f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-59418.stderr
@@ -0,0 +1,26 @@
+error: suffixes on a tuple index are invalid
+ --> $DIR/issue-59418.rs:5:15
+ |
+LL | let b = a.1suffix;
+ | ^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a tuple index are invalid
+ --> $DIR/issue-59418.rs:9:15
+ |
+LL | let d = c.1suffix;
+ | ^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a tuple index are invalid
+ --> $DIR/issue-59418.rs:12:17
+ |
+LL | let s = X { 0suffix: 0, 1: 1, 2: 2 };
+ | ^^^^^^^ invalid suffix `suffix`
+
+error: suffixes on a tuple index are invalid
+ --> $DIR/issue-59418.rs:15:13
+ |
+LL | X { 0suffix: _, .. } => {}
+ | ^^^^^^^ invalid suffix `suffix`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-60075.rs b/src/test/ui/parser/issues/issue-60075.rs
new file mode 100644
index 000000000..e89d78ee8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-60075.rs
@@ -0,0 +1,11 @@
+fn main() {}
+
+trait T {
+ fn qux() -> Option<usize> {
+ let _ = if true {
+ });
+//~^ ERROR non-item in item list
+//~| ERROR mismatched closing delimiter: `)`
+//~| ERROR expected one of `.`, `;`
+ Some(4)
+ }
diff --git a/src/test/ui/parser/issues/issue-60075.stderr b/src/test/ui/parser/issues/issue-60075.stderr
new file mode 100644
index 000000000..210ef700c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-60075.stderr
@@ -0,0 +1,29 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
+ --> $DIR/issue-60075.rs:6:10
+ |
+LL | });
+ | ^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: non-item in item list
+ --> $DIR/issue-60075.rs:6:11
+ |
+LL | trait T {
+ | - item list starts here
+...
+LL | });
+ | ^ non-item starts here
+...
+LL | }
+ | - item list ends here
+
+error: mismatched closing delimiter: `)`
+ --> $DIR/issue-60075.rs:4:31
+ |
+LL | fn qux() -> Option<usize> {
+ | ^ unclosed delimiter
+LL | let _ = if true {
+LL | });
+ | ^ mismatched closing delimiter
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-62524.rs b/src/test/ui/parser/issues/issue-62524.rs
new file mode 100644
index 000000000..5259dfe2e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62524.rs
@@ -0,0 +1,6 @@
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 3 previous errors
+#![allow(uncommon_codepoints)]
+
+y![
+Ϥ, \ No newline at end of file
diff --git a/src/test/ui/parser/issues/issue-62524.stderr b/src/test/ui/parser/issues/issue-62524.stderr
new file mode 100644
index 000000000..55eed0402
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62524.stderr
@@ -0,0 +1,33 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62524.rs:6:3
+ |
+LL | y![
+ | - unclosed delimiter
+LL | Ϥ,
+ | ^
+
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+ --> $DIR/issue-62524.rs:5:3
+ |
+LL | y![
+ | ___^
+LL | | Ϥ,
+ | |__^
+ |
+help: change the delimiters to curly braces
+ |
+LL | y! { /* items */ }
+ | ~~~~~~~~~~~~~~~
+help: add a semicolon
+ |
+LL | Ϥ,;
+ | +
+
+error: cannot find macro `y` in this scope
+ --> $DIR/issue-62524.rs:5:1
+ |
+LL | y![
+ | ^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-62546.rs b/src/test/ui/parser/issues/issue-62546.rs
new file mode 100644
index 000000000..f06b65058
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62546.rs
@@ -0,0 +1,3 @@
+pub t(#
+//~^ ERROR missing `fn` or `struct` for function or struct definition
+//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/issues/issue-62546.stderr b/src/test/ui/parser/issues/issue-62546.stderr
new file mode 100644
index 000000000..32c61391e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62546.stderr
@@ -0,0 +1,17 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62546.rs:3:52
+ |
+LL | pub t(#
+ | - unclosed delimiter
+LL |
+LL |
+ | ^
+
+error: missing `fn` or `struct` for function or struct definition
+ --> $DIR/issue-62546.rs:1:4
+ |
+LL | pub t(#
+ | ---^- help: if you meant to call a macro, try: `t!`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-62554.rs b/src/test/ui/parser/issues/issue-62554.rs
new file mode 100644
index 000000000..cfd02183c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62554.rs
@@ -0,0 +1,6 @@
+// error-pattern:this file contains an unclosed delimiter
+// error-pattern:xpected `{`, found `macro_rules`
+
+fn main() {}
+
+fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
diff --git a/src/test/ui/parser/issues/issue-62554.stderr b/src/test/ui/parser/issues/issue-62554.stderr
new file mode 100644
index 000000000..9e62572e3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62554.stderr
@@ -0,0 +1,73 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62554.rs:6:89
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | - - - - - ^
+ | | | | | |
+ | | | | | unclosed delimiter
+ | | | | unclosed delimiter
+ | | | unclosed delimiter
+ | unclosed delimiter unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62554.rs:6:89
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | - - - - - ^
+ | | | | | |
+ | | | | | unclosed delimiter
+ | | | | unclosed delimiter
+ | | | unclosed delimiter
+ | unclosed delimiter unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62554.rs:6:89
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | - - - - - ^
+ | | | | | |
+ | | | | | unclosed delimiter
+ | | | | unclosed delimiter
+ | | | unclosed delimiter
+ | unclosed delimiter unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62554.rs:6:89
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | - - - - - ^
+ | | | | | |
+ | | | | | unclosed delimiter
+ | | | | unclosed delimiter
+ | | | unclosed delimiter
+ | unclosed delimiter unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62554.rs:6:89
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | - - - - - ^
+ | | | | | |
+ | | | | | unclosed delimiter
+ | | | | unclosed delimiter
+ | | | unclosed delimiter
+ | unclosed delimiter unclosed delimiter
+
+error: expected `{`, found `macro_rules`
+ --> $DIR/issue-62554.rs:6:23
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | ^^^^^^^^^^^ expected `{`
+ |
+note: the `if` expression is missing a block after this condition
+ --> $DIR/issue-62554.rs:6:20
+ |
+LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
+ | ^^
+help: try placing this code inside a block
+ |
+LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { }
+ | + +
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-62660.rs b/src/test/ui/parser/issues/issue-62660.rs
new file mode 100644
index 000000000..33c8a9fa3
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62660.rs
@@ -0,0 +1,11 @@
+// Regression test for issue #62660: if a receiver's type does not
+// successfully parse, emit the correct error instead of ICE-ing the compiler.
+
+struct Foo;
+
+impl Foo {
+ pub fn foo(_: i32, self: Box<Self) {}
+ //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-62660.stderr b/src/test/ui/parser/issues/issue-62660.stderr
new file mode 100644
index 000000000..14c0bdcb1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62660.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)`
+ --> $DIR/issue-62660.rs:7:38
+ |
+LL | pub fn foo(_: i32, self: Box<Self) {}
+ | ^ expected one of 7 possible tokens
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | pub fn foo(_: i32, self: Box<Self>) {}
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-62881.rs b/src/test/ui/parser/issues/issue-62881.rs
new file mode 100644
index 000000000..b9204595f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62881.rs
@@ -0,0 +1,6 @@
+fn main() {}
+
+fn f() -> isize { fn f() -> isize {} pub f<
+//~^ ERROR missing `fn` or `struct` for function or struct definition
+//~| ERROR mismatched types
+//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/issues/issue-62881.stderr b/src/test/ui/parser/issues/issue-62881.stderr
new file mode 100644
index 000000000..87be69baa
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62881.stderr
@@ -0,0 +1,26 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62881.rs:6:52
+ |
+LL | fn f() -> isize { fn f() -> isize {} pub f<
+ | - unclosed delimiter
+...
+LL |
+ | ^
+
+error: missing `fn` or `struct` for function or struct definition
+ --> $DIR/issue-62881.rs:3:41
+ |
+LL | fn f() -> isize { fn f() -> isize {} pub f<
+ | ^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-62881.rs:3:29
+ |
+LL | fn f() -> isize { fn f() -> isize {} pub f<
+ | - ^^^^^ expected `isize`, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issues/issue-62894.rs b/src/test/ui/parser/issues/issue-62894.rs
new file mode 100644
index 000000000..b9c0bf834
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62894.rs
@@ -0,0 +1,7 @@
+// Regression test for #62894, shouldn't crash.
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn`
+
+fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-62894.stderr b/src/test/ui/parser/issues/issue-62894.stderr
new file mode 100644
index 000000000..ae8992691
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62894.stderr
@@ -0,0 +1,52 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62894.rs:7:14
+ |
+LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
+ | - - - unclosed delimiter
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+LL |
+LL | fn main() {}
+ | ^
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62894.rs:7:14
+ |
+LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
+ | - - - unclosed delimiter
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+LL |
+LL | fn main() {}
+ | ^
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62894.rs:7:14
+ |
+LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
+ | - - - unclosed delimiter
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+LL |
+LL | fn main() {}
+ | ^
+
+error: expected one of `(`, `[`, or `{`, found keyword `fn`
+ --> $DIR/issue-62894.rs:7:1
+ |
+LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
+ | - expected one of `(`, `[`, or `{`
+LL |
+LL | fn main() {}
+ | ^^ unexpected token
+ |
+ ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ |
+LL | ($left:expr, $right:expr $(,)?) => {
+ | ---------- while parsing argument for this `expr` macro fragment
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-62895.rs b/src/test/ui/parser/issues/issue-62895.rs
new file mode 100644
index 000000000..53f17405d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62895.rs
@@ -0,0 +1,11 @@
+fn main() {}
+
+fn v() -> isize { //~ ERROR mismatched types
+mod _ { //~ ERROR expected identifier
+pub fn g() -> isizee { //~ ERROR cannot find type `isizee` in this scope
+mod _ { //~ ERROR expected identifier
+pub g() -> is //~ ERROR missing `fn` for function definition
+(), w20);
+}
+(), w20); //~ ERROR expected item, found `;`
+}
diff --git a/src/test/ui/parser/issues/issue-62895.stderr b/src/test/ui/parser/issues/issue-62895.stderr
new file mode 100644
index 000000000..2e7e500f4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62895.stderr
@@ -0,0 +1,47 @@
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/issue-62895.rs:4:5
+ |
+LL | mod _ {
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/issue-62895.rs:6:5
+ |
+LL | mod _ {
+ | ^ expected identifier, found reserved identifier
+
+error: missing `fn` for function definition
+ --> $DIR/issue-62895.rs:7:4
+ |
+LL | pub g() -> is
+ | ^^^^
+ |
+help: add `fn` here to parse `g` as a public function
+ |
+LL | pub fn g() -> is
+ | ++
+
+error: expected item, found `;`
+ --> $DIR/issue-62895.rs:10:9
+ |
+LL | (), w20);
+ | ^ help: remove this semicolon
+
+error[E0412]: cannot find type `isizee` in this scope
+ --> $DIR/issue-62895.rs:5:15
+ |
+LL | pub fn g() -> isizee {
+ | ^^^^^^ help: a builtin type with a similar name exists: `isize`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-62895.rs:3:11
+ |
+LL | fn v() -> isize {
+ | - ^^^^^ expected `isize`, found `()`
+ | |
+ | implicitly returns `()` as its body has no tail or `return` expression
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0308, E0412.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issues/issue-62913.rs b/src/test/ui/parser/issues/issue-62913.rs
new file mode 100644
index 000000000..0db06f636
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62913.rs
@@ -0,0 +1,4 @@
+"\u\\"
+//~^ ERROR incorrect unicode escape sequence
+//~| ERROR invalid trailing slash in literal
+//~| ERROR expected item, found `"\u\\"`
diff --git a/src/test/ui/parser/issues/issue-62913.stderr b/src/test/ui/parser/issues/issue-62913.stderr
new file mode 100644
index 000000000..6f385e8dc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62913.stderr
@@ -0,0 +1,22 @@
+error: incorrect unicode escape sequence
+ --> $DIR/issue-62913.rs:1:2
+ |
+LL | "\u\"
+ | ^^^ incorrect unicode escape sequence
+ |
+ = help: format of unicode escape sequences is `\u{...}`
+
+error: invalid trailing slash in literal
+ --> $DIR/issue-62913.rs:1:5
+ |
+LL | "\u\"
+ | ^ invalid trailing slash in literal
+
+error: expected item, found `"\u\"`
+ --> $DIR/issue-62913.rs:1:1
+ |
+LL | "\u\"
+ | ^^^^^^ expected item
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-62973.rs b/src/test/ui/parser/issues/issue-62973.rs
new file mode 100644
index 000000000..1c5d0c6f8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62973.rs
@@ -0,0 +1,8 @@
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 7 previous errors
+
+fn main() {}
+
+fn p() { match s { v, E { [) {) }
+
+
diff --git a/src/test/ui/parser/issues/issue-62973.stderr b/src/test/ui/parser/issues/issue-62973.stderr
new file mode 100644
index 000000000..4737bc718
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-62973.stderr
@@ -0,0 +1,83 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62973.rs:8:2
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | - - unclosed delimiter
+ | |
+ | unclosed delimiter
+LL |
+LL |
+ | ^
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-62973.rs:8:2
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | - - unclosed delimiter
+ | |
+ | unclosed delimiter
+LL |
+LL |
+ | ^
+
+error: expected one of `,`, `:`, or `}`, found `{`
+ --> $DIR/issue-62973.rs:6:8
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | ^ - ^ expected one of `,`, `:`, or `}`
+ | | |
+ | | while parsing this struct
+ | unclosed delimiter
+ |
+help: `}` may belong here
+ |
+LL | fn p() { match s { v, E} { [) {) }
+ | +
+help: try naming a field
+ |
+LL | fn p() { match s { v, E: E { [) {) }
+ | ++
+
+error: struct literals are not allowed here
+ --> $DIR/issue-62973.rs:6:16
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | ________________^
+LL | |
+LL | |
+ | |_^
+ |
+help: surround the struct literal with parentheses
+ |
+LL ~ fn p() { match (s { v, E { [) {) }
+LL |
+LL ~ )
+ |
+
+error: expected one of `.`, `?`, `{`, or an operator, found `}`
+ --> $DIR/issue-62973.rs:8:2
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | ----- while parsing this `match` expression
+LL |
+LL |
+ | ^ expected one of `.`, `?`, `{`, or an operator
+
+error: mismatched closing delimiter: `)`
+ --> $DIR/issue-62973.rs:6:27
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | ^^ mismatched closing delimiter
+ | |
+ | unclosed delimiter
+
+error: mismatched closing delimiter: `)`
+ --> $DIR/issue-62973.rs:6:30
+ |
+LL | fn p() { match s { v, E { [) {) }
+ | ^^ mismatched closing delimiter
+ | |
+ | unclosed delimiter
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs b/src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs
new file mode 100644
index 000000000..8efb3c73f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-63115-range-pat-interpolated.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![feature(exclusive_range_pattern)]
+#![feature(half_open_range_patterns)]
+
+#![allow(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+ macro_rules! mac_expr {
+ ($e:expr) => {
+ if let 2...$e = 3 {}
+ if let 2..=$e = 3 {}
+ if let 2..$e = 3 {}
+ if let ..$e = 3 {}
+ if let ..=$e = 3 {}
+ if let $e.. = 5 {}
+ if let $e..5 = 4 {}
+ if let $e..=5 = 4 {}
+ }
+ }
+ mac_expr!(4);
+}
diff --git a/src/test/ui/parser/issues/issue-63116.rs b/src/test/ui/parser/issues/issue-63116.rs
new file mode 100644
index 000000000..430bc1d71
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-63116.rs
@@ -0,0 +1,3 @@
+// fixed by #66361
+// error-pattern: aborting due to 3 previous errors
+impl W <s(f;Y(;]
diff --git a/src/test/ui/parser/issues/issue-63116.stderr b/src/test/ui/parser/issues/issue-63116.stderr
new file mode 100644
index 000000000..cfdd99d14
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-63116.stderr
@@ -0,0 +1,24 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-63116.rs:3:18
+ |
+LL | impl W <s(f;Y(;]
+ | - ^
+ | |
+ | unclosed delimiter
+
+error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `;`
+ --> $DIR/issue-63116.rs:3:12
+ |
+LL | impl W <s(f;Y(;]
+ | ^ expected one of 7 possible tokens
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-63116.rs:3:14
+ |
+LL | impl W <s(f;Y(;]
+ | ^ ^ mismatched closing delimiter
+ | |
+ | unclosed delimiter
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-63135.rs b/src/test/ui/parser/issues/issue-63135.rs
new file mode 100644
index 000000000..a5a8de854
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-63135.rs
@@ -0,0 +1,3 @@
+// error-pattern: aborting due to 5 previous errors
+
+fn i(n{...,f #
diff --git a/src/test/ui/parser/issues/issue-63135.stderr b/src/test/ui/parser/issues/issue-63135.stderr
new file mode 100644
index 000000000..80e9ac5be
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-63135.stderr
@@ -0,0 +1,43 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-63135.rs:3:16
+ |
+LL | fn i(n{...,f #
+ | - - ^
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-63135.rs:3:16
+ |
+LL | fn i(n{...,f #
+ | - - ^
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+
+error: expected field pattern, found `...`
+ --> $DIR/issue-63135.rs:3:8
+ |
+LL | fn i(n{...,f #
+ | ^^^ help: to omit remaining fields, use one fewer `.`: `..`
+
+error: expected `}`, found `,`
+ --> $DIR/issue-63135.rs:3:11
+ |
+LL | fn i(n{...,f #
+ | ---^
+ | | |
+ | | expected `}`
+ | `..` must be at the end and cannot have a trailing comma
+
+error: expected one of `!` or `[`, found `}`
+ --> $DIR/issue-63135.rs:3:16
+ |
+LL | fn i(n{...,f #
+ | - ^ expected one of `!` or `[`
+ | |
+ | while parsing the fields for this pattern
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-64732.rs b/src/test/ui/parser/issues/issue-64732.rs
new file mode 100644
index 000000000..2db51ea60
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-64732.rs
@@ -0,0 +1,9 @@
+#![allow(unused)]
+fn main() {
+ let _foo = b'hello\0';
+ //~^ ERROR character literal may only contain one codepoint
+ //~| HELP if you meant to write a byte string literal, use double quotes
+ let _bar = 'hello';
+ //~^ ERROR character literal may only contain one codepoint
+ //~| HELP if you meant to write a `str` literal, use double quotes
+}
diff --git a/src/test/ui/parser/issues/issue-64732.stderr b/src/test/ui/parser/issues/issue-64732.stderr
new file mode 100644
index 000000000..804625493
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-64732.stderr
@@ -0,0 +1,24 @@
+error: character literal may only contain one codepoint
+ --> $DIR/issue-64732.rs:3:16
+ |
+LL | let _foo = b'hello\0';
+ | ^^^^^^^^^^
+ |
+help: if you meant to write a byte string literal, use double quotes
+ |
+LL | let _foo = b"hello\0";
+ | ~~~~~~~~~~
+
+error: character literal may only contain one codepoint
+ --> $DIR/issue-64732.rs:6:16
+ |
+LL | let _bar = 'hello';
+ | ^^^^^^^
+ |
+help: if you meant to write a `str` literal, use double quotes
+ |
+LL | let _bar = "hello";
+ | ~~~~~~~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs
new file mode 100644
index 000000000..ef89e31d8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-enum.rs
@@ -0,0 +1,28 @@
+// check-pass
+
+// Here we check that a `:vis` macro matcher subsititued for the empty visibility
+// (`VisibilityKind::Inherited`) is accepted when used before an enum variant.
+
+fn main() {}
+
+macro_rules! mac_variant {
+ ($vis:vis MARKER) => {
+ enum Enum {
+ $vis Unit,
+
+ $vis Tuple(u8, u16),
+
+ $vis Struct { f: u8 },
+ }
+ }
+}
+
+mac_variant!(MARKER);
+
+// We also accept visibilities on variants syntactically but not semantically.
+#[cfg(FALSE)]
+enum E {
+ pub U,
+ pub(crate) T(u8),
+ pub(super) T { f: String }
+}
diff --git a/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs
new file mode 100644
index 000000000..b08767b21
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs
@@ -0,0 +1,28 @@
+// check-pass
+
+// Here we check that a `:vis` macro matcher subsititued for the empty visibility
+// (`VisibilityKind::Inherited`) is accepted when used before an item in a trait.
+
+fn main() {}
+
+macro_rules! mac_in_trait {
+ ($vis:vis MARKER) => {
+ $vis fn beta() {}
+
+ $vis const GAMMA: u8;
+
+ $vis type Delta;
+ }
+}
+
+trait Alpha {
+ mac_in_trait!(MARKER);
+}
+
+// We also accept visibilities on items in traits syntactically but not semantically.
+#[cfg(FALSE)]
+trait Foo {
+ pub fn bar();
+ pub(crate) type baz;
+ pub(super) const QUUX: u8;
+}
diff --git a/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs
new file mode 100644
index 000000000..30f3781bf
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs
@@ -0,0 +1,26 @@
+// Regression test; used to ICE with 'visit_mac_call disabled by default' due to a
+// `MutVisitor` in `fn make_all_value_bindings_mutable` (`parse/parser/pat.rs`).
+
+macro_rules! mac1 {
+ ($eval:expr) => {
+ let mut $eval = ();
+ //~^ ERROR `mut` must be followed by a named binding
+ };
+}
+
+macro_rules! mac2 {
+ ($eval:pat) => {
+ let mut $eval = ();
+ //~^ ERROR `mut` must be followed by a named binding
+ //~| ERROR expected identifier, found `does_not_exist!()`
+ };
+}
+
+fn foo() {
+ mac1! { does_not_exist!() }
+ //~^ ERROR cannot find macro `does_not_exist` in this scope
+ mac2! { does_not_exist!() }
+ //~^ ERROR cannot find macro `does_not_exist` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr
new file mode 100644
index 000000000..8c032e588
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr
@@ -0,0 +1,49 @@
+error: `mut` must be followed by a named binding
+ --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:6:13
+ |
+LL | let mut $eval = ();
+ | ^^^^^^^^^ help: remove the `mut` prefix: `does_not_exist!()`
+...
+LL | mac1! { does_not_exist!() }
+ | --------------------------- in this macro invocation
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+ = note: this error originates in the macro `mac1` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected identifier, found `does_not_exist!()`
+ --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:17
+ |
+LL | let mut $eval = ();
+ | ^^^^^ expected identifier
+...
+LL | mac2! { does_not_exist!() }
+ | --------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `mut` must be followed by a named binding
+ --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:13
+ |
+LL | let mut $eval = ();
+ | ^^^ help: remove the `mut` prefix: `does_not_exist!()`
+...
+LL | mac2! { does_not_exist!() }
+ | --------------------------- in this macro invocation
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+ = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot find macro `does_not_exist` in this scope
+ --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13
+ |
+LL | mac2! { does_not_exist!() }
+ | ^^^^^^^^^^^^^^
+
+error: cannot find macro `does_not_exist` in this scope
+ --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13
+ |
+LL | mac1! { does_not_exist!() }
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs
new file mode 100644
index 000000000..c1826f8ca
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.rs
@@ -0,0 +1,21 @@
+fn main() {
+ auto n = 0;//~ ERROR invalid variable declaration
+ //~^ HELP write `let` instead of `auto` to introduce a new variable
+ auto m;//~ ERROR invalid variable declaration
+ //~^ HELP write `let` instead of `auto` to introduce a new variable
+ m = 0;
+
+ var n = 0;//~ ERROR invalid variable declaration
+ //~^ HELP write `let` instead of `var` to introduce a new variable
+ var m;//~ ERROR invalid variable declaration
+ //~^ HELP write `let` instead of `var` to introduce a new variable
+ m = 0;
+
+ mut n = 0;//~ ERROR invalid variable declaration
+ //~^ HELP missing keyword
+ mut var;//~ ERROR invalid variable declaration
+ //~^ HELP missing keyword
+ var = 0;
+
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr
new file mode 100644
index 000000000..0a88dd2c4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65257-invalid-var-decl-recovery.stderr
@@ -0,0 +1,67 @@
+error: invalid variable declaration
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:2:5
+ |
+LL | auto n = 0;
+ | ^^^^
+ |
+help: write `let` instead of `auto` to introduce a new variable
+ |
+LL | let n = 0;
+ | ~~~
+
+error: invalid variable declaration
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:4:5
+ |
+LL | auto m;
+ | ^^^^
+ |
+help: write `let` instead of `auto` to introduce a new variable
+ |
+LL | let m;
+ | ~~~
+
+error: invalid variable declaration
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:8:5
+ |
+LL | var n = 0;
+ | ^^^
+ |
+help: write `let` instead of `var` to introduce a new variable
+ |
+LL | let n = 0;
+ | ~~~
+
+error: invalid variable declaration
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:10:5
+ |
+LL | var m;
+ | ^^^
+ |
+help: write `let` instead of `var` to introduce a new variable
+ |
+LL | let m;
+ | ~~~
+
+error: invalid variable declaration
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:14:5
+ |
+LL | mut n = 0;
+ | ^^^ help: missing keyword: `let mut`
+
+error: invalid variable declaration
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:16:5
+ |
+LL | mut var;
+ | ^^^ help: missing keyword: `let mut`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-65257-invalid-var-decl-recovery.rs:20:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs b/src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs
new file mode 100644
index 000000000..76c07bbfd
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-65846-rollback-gating-failing-matcher.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+// Test that failing macro matchers will not cause pre-expansion errors
+// even though they use a feature that is pre-expansion gated.
+
+#[allow(unused_macro_rules)]
+macro_rules! m {
+ ($e:expr) => { 0 }; // This fails on the input below due to `, foo`.
+ ($e:expr,) => { 1 }; // This also fails to match due to `foo`.
+ (box $e:expr, foo) => { 2 }; // Successful matcher, we should get `2`.
+}
+
+fn main() {
+ assert_eq!(2, m!(box 42, foo));
+}
diff --git a/src/test/ui/parser/issues/issue-6610.rs b/src/test/ui/parser/issues/issue-6610.rs
new file mode 100644
index 000000000..9ed5a6122
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-6610.rs
@@ -0,0 +1,3 @@
+trait Foo { fn a() } //~ ERROR expected one of `->`, `;`, `where`, or `{`, found `}`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-6610.stderr b/src/test/ui/parser/issues/issue-6610.stderr
new file mode 100644
index 000000000..4a3bc7525
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-6610.stderr
@@ -0,0 +1,10 @@
+error: expected one of `->`, `;`, `where`, or `{`, found `}`
+ --> $DIR/issue-6610.rs:1:20
+ |
+LL | trait Foo { fn a() }
+ | - ^ expected one of `->`, `;`, `where`, or `{`
+ | |
+ | while parsing this `fn`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs
new file mode 100644
index 000000000..aed428bfc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.rs
@@ -0,0 +1,14 @@
+// The problem in #66357 was that the call trace:
+//
+// - parse_fn_block_decl
+// - expect_or
+// - unexpected
+// - expect_one_of
+// - expected_one_of_not_found
+// - recover_closing_delimiter
+//
+// ended up bubbling up `Ok(true)` to `unexpected` which then used `unreachable!()`.
+
+fn f() { |[](* }
+//~^ ERROR expected one of `,` or `:`, found `(`
+//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`
diff --git a/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr
new file mode 100644
index 000000000..6cbab855c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-66357-unexpected-unreachable.stderr
@@ -0,0 +1,16 @@
+error: expected one of `,` or `:`, found `(`
+ --> $DIR/issue-66357-unexpected-unreachable.rs:12:13
+ |
+LL | fn f() { |[](* }
+ | ^ expected one of `,` or `:`
+
+error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`
+ --> $DIR/issue-66357-unexpected-unreachable.rs:12:13
+ |
+LL | fn f() { |[](* }
+ | ^^ help: `)` may belong here
+ | |
+ | unclosed delimiter
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-66473.rs b/src/test/ui/parser/issues/issue-66473.rs
new file mode 100644
index 000000000..9db4521bb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-66473.rs
Binary files differ
diff --git a/src/test/ui/parser/issues/issue-66473.stderr b/src/test/ui/parser/issues/issue-66473.stderr
new file mode 100644
index 000000000..8a16d7f95
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-66473.stderr
Binary files differ
diff --git a/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed
new file mode 100644
index 000000000..95019b278
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+// In this regression test for #67146, we check that the
+// negative outlives bound `!'a` is rejected by the parser.
+// This regression was first introduced in PR #57364.
+
+fn main() {}
+
+pub fn f1<T>() {}
+//~^ ERROR negative bounds are not supported
+pub fn f2<'a, T: Ord>() {}
+//~^ ERROR negative bounds are not supported
+pub fn f3<'a, T: Ord>() {}
+//~^ ERROR negative bounds are not supported
diff --git a/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs
new file mode 100644
index 000000000..82f54f8fa
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+// In this regression test for #67146, we check that the
+// negative outlives bound `!'a` is rejected by the parser.
+// This regression was first introduced in PR #57364.
+
+fn main() {}
+
+pub fn f1<T: !'static>() {}
+//~^ ERROR negative bounds are not supported
+pub fn f2<'a, T: Ord + !'a>() {}
+//~^ ERROR negative bounds are not supported
+pub fn f3<'a, T: !'a + Ord>() {}
+//~^ ERROR negative bounds are not supported
diff --git a/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr
new file mode 100644
index 000000000..a4a422948
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-67146-negative-outlives-bound-syntactic-fail.stderr
@@ -0,0 +1,20 @@
+error: negative bounds are not supported
+ --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:12
+ |
+LL | pub fn f1<T: !'static>() {}
+ | ^^^^^^^^^^ negative bounds are not supported
+
+error: negative bounds are not supported
+ --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:11:22
+ |
+LL | pub fn f2<'a, T: Ord + !'a>() {}
+ | ^^^^^ negative bounds are not supported
+
+error: negative bounds are not supported
+ --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:13:16
+ |
+LL | pub fn f3<'a, T: !'a + Ord>() {}
+ | ^^^^^ negative bounds are not supported
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs
new file mode 100644
index 000000000..87222ef4b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.rs
@@ -0,0 +1,35 @@
+mod a {
+ use std::marker::PhantomData;
+
+ enum Bug {
+ V = [PhantomData; { [ () ].len() ].len() as isize,
+ //~^ ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ }
+}
+
+mod b {
+ enum Bug {
+ V = [Vec::new; { [].len() ].len() as isize,
+ //~^ ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR type annotations needed
+ }
+}
+
+mod c {
+ enum Bug {
+ V = [Vec::new; { [0].len() ].len() as isize,
+ //~^ ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR mismatched closing delimiter: `]`
+ //~| ERROR type annotations needed
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
new file mode 100644
index 000000000..85c9fe409
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
@@ -0,0 +1,128 @@
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
+ |
+LL | V = [PhantomData; { [ () ].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
+ |
+LL | V = [Vec::new; { [].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
+ |
+LL | V = [Vec::new; { [0].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
+ |
+LL | V = [PhantomData; { [ () ].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
+ |
+LL | V = [Vec::new; { [].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
+ |
+LL | V = [Vec::new; { [0].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
+ |
+LL | V = [PhantomData; { [ () ].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
+ |
+LL | V = [Vec::new; { [].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
+ |
+LL | V = [Vec::new; { [0].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27
+ |
+LL | V = [PhantomData; { [ () ].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:24
+ |
+LL | V = [Vec::new; { [].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:24
+ |
+LL | V = [Vec::new; { [0].len() ].len() as isize,
+ | - ^ ^ mismatched closing delimiter
+ | | |
+ | | unclosed delimiter
+ | closing delimiter possibly meant for this
+
+error[E0282]: type annotations needed
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29
+ |
+LL | V = [Vec::new; { [].len() ].len() as isize,
+ | ^^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+ --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14
+ |
+LL | V = [Vec::new; { [0].len() ].len() as isize,
+ | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec`
+ |
+help: consider specifying the generic argument
+ |
+LL | V = [Vec::<T>::new; { [0].len() ].len() as isize,
+ | +++++
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs
new file mode 100644
index 000000000..3c49a5a97
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.rs
@@ -0,0 +1,6 @@
+pub struct Foo {
+ pub bar: Vec<i32>ö
+ //~^ ERROR expected `,`, or `}`, found `ö`
+} //~ ERROR expected `:`, found `}`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr
new file mode 100644
index 000000000..ef365a616
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr
@@ -0,0 +1,17 @@
+error: expected `,`, or `}`, found `ö`
+ --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22
+ |
+LL | pub bar: Vec<i32>ö
+ | ^ help: try adding a comma: `,`
+
+error: expected `:`, found `}`
+ --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1
+ |
+LL | pub bar: Vec<i32>ö
+ | - expected `:`
+LL |
+LL | }
+ | ^ unexpected token
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-68629.rs b/src/test/ui/parser/issues/issue-68629.rs
new file mode 100644
index 000000000..672a31f12
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68629.rs
Binary files differ
diff --git a/src/test/ui/parser/issues/issue-68629.stderr b/src/test/ui/parser/issues/issue-68629.stderr
new file mode 100644
index 000000000..b2c7dddc8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68629.stderr
Binary files differ
diff --git a/src/test/ui/parser/issues/issue-68730.rs b/src/test/ui/parser/issues/issue-68730.rs
new file mode 100644
index 000000000..20e18b4bc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68730.rs
Binary files differ
diff --git a/src/test/ui/parser/issues/issue-68730.stderr b/src/test/ui/parser/issues/issue-68730.stderr
new file mode 100644
index 000000000..6585a19d9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68730.stderr
Binary files differ
diff --git a/src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs b/src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs
new file mode 100644
index 000000000..7c3dd1d5a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68788-in-trait-item-propagation.rs
@@ -0,0 +1,21 @@
+// Make sure we don't propagate restrictions on trait impl items to items inside them.
+
+// check-pass
+// edition:2018
+
+fn main() {}
+
+trait X {
+ fn foo();
+}
+
+impl X for () {
+ fn foo() {
+ struct S;
+ impl S {
+ pub const X: u8 = 0;
+ pub const fn bar() {}
+ async fn qux() {}
+ }
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-68890-2.rs b/src/test/ui/parser/issues/issue-68890-2.rs
new file mode 100644
index 000000000..29c123521
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68890-2.rs
@@ -0,0 +1,5 @@
+fn main() {}
+
+type X<'a> = (?'a) +;
+//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
+//~| ERROR at least one trait is required for an object type
diff --git a/src/test/ui/parser/issues/issue-68890-2.stderr b/src/test/ui/parser/issues/issue-68890-2.stderr
new file mode 100644
index 000000000..d9fb7beeb
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68890-2.stderr
@@ -0,0 +1,15 @@
+error: `?` may only modify trait bounds, not lifetime bounds
+ --> $DIR/issue-68890-2.rs:3:15
+ |
+LL | type X<'a> = (?'a) +;
+ | ^
+
+error[E0224]: at least one trait is required for an object type
+ --> $DIR/issue-68890-2.rs:3:14
+ |
+LL | type X<'a> = (?'a) +;
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0224`.
diff --git a/src/test/ui/parser/issues/issue-68890.rs b/src/test/ui/parser/issues/issue-68890.rs
new file mode 100644
index 000000000..bab4ed7f8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68890.rs
@@ -0,0 +1,4 @@
+enum e{A((?'a a+?+l))}
+//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
+//~| ERROR expected one of `)`, `+`, or `,`
+//~| ERROR expected item, found `)`
diff --git a/src/test/ui/parser/issues/issue-68890.stderr b/src/test/ui/parser/issues/issue-68890.stderr
new file mode 100644
index 000000000..2a3bf6b41
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-68890.stderr
@@ -0,0 +1,20 @@
+error: `?` may only modify trait bounds, not lifetime bounds
+ --> $DIR/issue-68890.rs:1:11
+ |
+LL | enum e{A((?'a a+?+l))}
+ | ^
+
+error: expected one of `)`, `+`, or `,`, found `a`
+ --> $DIR/issue-68890.rs:1:15
+ |
+LL | enum e{A((?'a a+?+l))}
+ | ^ expected one of `)`, `+`, or `,`
+
+error: expected item, found `)`
+ --> $DIR/issue-68890.rs:1:21
+ |
+LL | enum e{A((?'a a+?+l))}
+ | ^ expected item
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs b/src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs
new file mode 100644
index 000000000..aca9d9eb0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70050-ntliteral-accepts-negated-lit.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+macro_rules! foo {
+ ($a:literal) => {
+ bar!($a)
+ };
+}
+
+macro_rules! bar {
+ ($b:literal) => {};
+}
+
+fn main() {
+ foo!(-2);
+ bar!(-2);
+}
diff --git a/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs
new file mode 100644
index 000000000..ca8abd78c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.rs
@@ -0,0 +1,7 @@
+struct Foo(i32);
+
+fn main() {
+ let Foo(...) = Foo(0); //~ ERROR unexpected `...`
+ let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...`
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr
new file mode 100644
index 000000000..4961e8fc0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70388-recover-dotdotdot-rest-pat.stderr
@@ -0,0 +1,29 @@
+error: unexpected `...`
+ --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:4:13
+ |
+LL | let Foo(...) = Foo(0);
+ | ^^^
+ | |
+ | not a valid pattern
+ | help: for a rest pattern, use `..` instead of `...`
+
+error: unexpected `...`
+ --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:5:13
+ |
+LL | let [_, ..., _] = [0, 1];
+ | ^^^
+ | |
+ | not a valid pattern
+ | help: for a rest pattern, use `..` instead of `...`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:6:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.fixed b/src/test/ui/parser/issues/issue-70388-without-witness.fixed
new file mode 100644
index 000000000..8d981405e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70388-without-witness.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+// This is for checking if we can apply suggestions as-is.
+
+pub struct Foo(#[allow(unused_tuple_struct_fields)] i32);
+
+fn main() {
+ let Foo(..) = Foo(0); //~ ERROR unexpected `...`
+ let [_, .., _] = [0, 1]; //~ ERROR unexpected `...`
+}
diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.rs b/src/test/ui/parser/issues/issue-70388-without-witness.rs
new file mode 100644
index 000000000..bf3607308
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70388-without-witness.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+// This is for checking if we can apply suggestions as-is.
+
+pub struct Foo(#[allow(unused_tuple_struct_fields)] i32);
+
+fn main() {
+ let Foo(...) = Foo(0); //~ ERROR unexpected `...`
+ let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...`
+}
diff --git a/src/test/ui/parser/issues/issue-70388-without-witness.stderr b/src/test/ui/parser/issues/issue-70388-without-witness.stderr
new file mode 100644
index 000000000..b750ad4c6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70388-without-witness.stderr
@@ -0,0 +1,20 @@
+error: unexpected `...`
+ --> $DIR/issue-70388-without-witness.rs:7:13
+ |
+LL | let Foo(...) = Foo(0);
+ | ^^^
+ | |
+ | not a valid pattern
+ | help: for a rest pattern, use `..` instead of `...`
+
+error: unexpected `...`
+ --> $DIR/issue-70388-without-witness.rs:8:13
+ |
+LL | let [_, ..., _] = [0, 1];
+ | ^^^
+ | |
+ | not a valid pattern
+ | help: for a rest pattern, use `..` instead of `...`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs
new file mode 100644
index 000000000..aeccd0d9f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs
@@ -0,0 +1,18 @@
+struct S {}
+
+impl S {
+ fn foo(&mur Self) {}
+ //~^ ERROR expected identifier, found keyword `Self`
+ //~| ERROR expected one of `:`, `@`
+ //~| ERROR the `Self` constructor can only be used with
+ fn bar(&'static mur Self) {}
+ //~^ ERROR unexpected lifetime
+ //~| ERROR expected identifier, found keyword `Self`
+ //~| ERROR expected one of `:`, `@`
+ //~| ERROR the `Self` constructor can only be used with
+
+ fn baz(&mur Self @ _) {}
+ //~^ ERROR expected one of `:`, `@`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
new file mode 100644
index 000000000..421f14540
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
@@ -0,0 +1,56 @@
+error: expected identifier, found keyword `Self`
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
+ |
+LL | fn foo(&mur Self) {}
+ | ^^^^ expected identifier, found keyword
+
+error: expected one of `:`, `@`, or `|`, found keyword `Self`
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
+ |
+LL | fn foo(&mur Self) {}
+ | -----^^^^
+ | | |
+ | | expected one of `:`, `@`, or `|`
+ | help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: unexpected lifetime `'static` in pattern
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:13
+ |
+LL | fn bar(&'static mur Self) {}
+ | ^^^^^^^ help: remove the lifetime
+
+error: expected identifier, found keyword `Self`
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
+ |
+LL | fn bar(&'static mur Self) {}
+ | ^^^^ expected identifier, found keyword
+
+error: expected one of `:`, `@`, or `|`, found keyword `Self`
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
+ |
+LL | fn bar(&'static mur Self) {}
+ | -------------^^^^
+ | | |
+ | | expected one of `:`, `@`, or `|`
+ | help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: expected one of `:`, `@`, or `|`, found keyword `Self`
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:14:17
+ |
+LL | fn baz(&mur Self @ _) {}
+ | ^^^^ expected one of `:`, `@`, or `|`
+
+error: the `Self` constructor can only be used with tuple or unit structs
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
+ |
+LL | fn foo(&mur Self) {}
+ | ^^^^ help: use curly brackets: `Self { /* fields */ }`
+
+error: the `Self` constructor can only be used with tuple or unit structs
+ --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
+ |
+LL | fn bar(&'static mur Self) {}
+ | ^^^^ help: use curly brackets: `Self { /* fields */ }`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs
new file mode 100644
index 000000000..9b6dd7db4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.rs
@@ -0,0 +1,3 @@
+fn main() {
+ expr as fun()(:); //~ ERROR expected expression
+}
diff --git a/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr
new file mode 100644
index 000000000..f03c92e1b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70552-ascription-in-parens-after-call.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `:`
+ --> $DIR/issue-70552-ascription-in-parens-after-call.rs:2:19
+ |
+LL | expr as fun()(:);
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs
new file mode 100644
index 000000000..f560f68f6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.rs
@@ -0,0 +1,20 @@
+pub enum ErrorHandled {
+ Reported,
+ TooGeneric,
+}
+
+impl ErrorHandled {
+ pub fn assert_reported(self) {
+ match self {
+ ErrorHandled::Reported => {}
+ ErrorHandled::TooGeneric => panic!(),
+ }
+ }
+}
+
+fn struct_generic(x: Vec<i32>) {
+ for v in x {
+ println!("{}", v);
+ }
+ }
+} //~ ERROR unexpected closing delimiter: `}`
diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr
new file mode 100644
index 000000000..39bf113ef
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-1.stderr
@@ -0,0 +1,13 @@
+error: unexpected closing delimiter: `}`
+ --> $DIR/issue-70583-block-is-empty-1.rs:20:1
+ |
+LL | fn struct_generic(x: Vec<i32>) {
+ | - this opening brace...
+...
+LL | }
+ | - ...matches this closing brace
+LL | }
+ | ^ unexpected closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs
new file mode 100644
index 000000000..80f53338a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.rs
@@ -0,0 +1,14 @@
+pub enum ErrorHandled {
+ Reported,
+ TooGeneric,
+}
+
+impl ErrorHandled {
+ pub fn assert_reported(self) {
+ match self {
+ ErrorHandled::Reported => {}}
+ //^~ ERROR block is empty, you might have not meant to close it
+ ErrorHandled::TooGeneric => panic!(),
+ }
+ }
+} //~ ERROR unexpected closing delimiter: `}`
diff --git a/src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr
new file mode 100644
index 000000000..5d37b2164
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-70583-block-is-empty-2.stderr
@@ -0,0 +1,11 @@
+error: unexpected closing delimiter: `}`
+ --> $DIR/issue-70583-block-is-empty-2.rs:14:1
+ |
+LL | ErrorHandled::Reported => {}}
+ | -- block is empty, you might have not meant to close it
+...
+LL | }
+ | ^ unexpected closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-7222.rs b/src/test/ui/parser/issues/issue-7222.rs
new file mode 100644
index 000000000..649073166
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-7222.rs
@@ -0,0 +1,12 @@
+// run-pass
+// pretty-expanded FIXME #23616
+#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620
+
+pub fn main() {
+ const FOO: f64 = 10.0;
+
+ match 0.0 {
+ 0.0 ..= FOO => (),
+ _ => ()
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-72253.rs b/src/test/ui/parser/issues/issue-72253.rs
new file mode 100644
index 000000000..1446a796f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-72253.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let a = std::process::Command::new("echo")
+ .arg("1")
+ ,arg("2") //~ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `,`
+ .output();
+}
diff --git a/src/test/ui/parser/issues/issue-72253.stderr b/src/test/ui/parser/issues/issue-72253.stderr
new file mode 100644
index 000000000..477fa09f4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-72253.stderr
@@ -0,0 +1,10 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `,`
+ --> $DIR/issue-72253.rs:4:9
+ |
+LL | .arg("1")
+ | - expected one of `.`, `;`, `?`, `else`, or an operator
+LL | ,arg("2")
+ | ^ unexpected token
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-72373.rs b/src/test/ui/parser/issues/issue-72373.rs
new file mode 100644
index 000000000..4da6061c2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-72373.rs
@@ -0,0 +1,9 @@
+fn foo(c: &[u32], n: u32) -> u32 {
+ match *c {
+ [h, ..] if h > n => 0,
+ [h, ..] if h == n => 1,
+ [h, ref ts..] => foo(c, n - h) + foo(ts, n),
+ //~^ ERROR expected one of `,`, `@`, `]`, or `|`, found `..`
+ [] => 0,
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-72373.stderr b/src/test/ui/parser/issues/issue-72373.stderr
new file mode 100644
index 000000000..0bb99a01e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-72373.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,`, `@`, `]`, or `|`, found `..`
+ --> $DIR/issue-72373.rs:5:19
+ |
+LL | [h, ref ts..] => foo(c, n - h) + foo(ts, n),
+ | ^^ expected one of `,`, `@`, `]`, or `|`
+ |
+help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@`
+ |
+LL | [h, ref ts @ ..] => foo(c, n - h) + foo(ts, n),
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs
new file mode 100644
index 000000000..5f731f8db
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.rs
@@ -0,0 +1,19 @@
+#![crate_type="lib"]
+fn x<'a>(x: &mut 'a i32){} //~ ERROR lifetime must precede `mut`
+
+macro_rules! mac {
+ ($lt:lifetime) => {
+ fn w<$lt>(w: &mut $lt i32) {}
+ //~^ ERROR lifetime must precede `mut`
+ }
+}
+
+mac!('a);
+
+// avoid false positives
+fn y<'a>(y: &mut 'a + Send) {
+ //~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a`
+ //~| ERROR at least one trait is required for an object type
+ let z = y as &mut 'a + Send;
+ //~^ ERROR expected value, found trait `Send`
+}
diff --git a/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr
new file mode 100644
index 000000000..799bc16bd
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-73568-lifetime-after-mut.stderr
@@ -0,0 +1,39 @@
+error: lifetime must precede `mut`
+ --> $DIR/issue-73568-lifetime-after-mut.rs:2:13
+ |
+LL | fn x<'a>(x: &mut 'a i32){}
+ | ^^^^^^^ help: place the lifetime before `mut`: `&'a mut`
+
+error[E0178]: expected a path on the left-hand side of `+`, not `&mut 'a`
+ --> $DIR/issue-73568-lifetime-after-mut.rs:14:13
+ |
+LL | fn y<'a>(y: &mut 'a + Send) {
+ | ^^^^^^^^^^^^^^ help: try adding parentheses: `&mut ('a + Send)`
+
+error: lifetime must precede `mut`
+ --> $DIR/issue-73568-lifetime-after-mut.rs:6:22
+ |
+LL | fn w<$lt>(w: &mut $lt i32) {}
+ | ^^^^^^^^ help: place the lifetime before `mut`: `&$lt mut`
+...
+LL | mac!('a);
+ | -------- in this macro invocation
+ |
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found trait `Send`
+ --> $DIR/issue-73568-lifetime-after-mut.rs:17:28
+ |
+LL | let z = y as &mut 'a + Send;
+ | ^^^^ not a value
+
+error[E0224]: at least one trait is required for an object type
+ --> $DIR/issue-73568-lifetime-after-mut.rs:14:18
+ |
+LL | fn y<'a>(y: &mut 'a + Send) {
+ | ^^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0178, E0224, E0423.
+For more information about an error, try `rustc --explain E0178`.
diff --git a/src/test/ui/parser/issues/issue-75599.rs b/src/test/ui/parser/issues/issue-75599.rs
new file mode 100644
index 000000000..0857676e4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-75599.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![allow(non_upper_case_globals)]
+
+const or: usize = 1;
+const and: usize = 2;
+
+mod or {
+ pub const X: usize = 3;
+}
+
+mod and {
+ pub const X: usize = 4;
+}
+
+fn main() {
+ match 0 {
+ 0 => {}
+ or => {}
+ and => {}
+ or::X => {}
+ and::X => {}
+ _ => {}
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-76437-async.rs b/src/test/ui/parser/issues/issue-76437-async.rs
new file mode 100644
index 000000000..84ee3dd21
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-async.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+mod t {
+ async pub fn t() {}
+ //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+ //~| HELP visibility `pub` must come before `async`
+}
diff --git a/src/test/ui/parser/issues/issue-76437-async.stderr b/src/test/ui/parser/issues/issue-76437-async.stderr
new file mode 100644
index 000000000..2c9c2a8cf
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-async.stderr
@@ -0,0 +1,11 @@
+error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+ --> $DIR/issue-76437-async.rs:4:11
+ |
+LL | async pub fn t() {}
+ | ------^^^
+ | | |
+ | | expected one of `extern`, `fn`, or `unsafe`
+ | help: visibility `pub` must come before `async`: `pub async`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs
new file mode 100644
index 000000000..f1e06e4ad
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+mod t {
+ const async unsafe pub fn t() {}
+ //~^ ERROR expected one of `extern` or `fn`, found keyword `pub`
+ //~| HELP visibility `pub` must come before `const async unsafe`
+}
diff --git a/src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr
new file mode 100644
index 000000000..2e91beda1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-const-async-unsafe.stderr
@@ -0,0 +1,11 @@
+error: expected one of `extern` or `fn`, found keyword `pub`
+ --> $DIR/issue-76437-const-async-unsafe.rs:4:24
+ |
+LL | const async unsafe pub fn t() {}
+ | -------------------^^^
+ | | |
+ | | expected one of `extern` or `fn`
+ | help: visibility `pub` must come before `const async unsafe`: `pub const async unsafe`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-76437-const-async.rs b/src/test/ui/parser/issues/issue-76437-const-async.rs
new file mode 100644
index 000000000..3c789fdcd
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-const-async.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+mod t {
+ const async pub fn t() {}
+ //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+ //~| HELP visibility `pub` must come before `const async`
+}
diff --git a/src/test/ui/parser/issues/issue-76437-const-async.stderr b/src/test/ui/parser/issues/issue-76437-const-async.stderr
new file mode 100644
index 000000000..21b96c14d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-const-async.stderr
@@ -0,0 +1,11 @@
+error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+ --> $DIR/issue-76437-const-async.rs:4:17
+ |
+LL | const async pub fn t() {}
+ | ------------^^^
+ | | |
+ | | expected one of `extern`, `fn`, or `unsafe`
+ | help: visibility `pub` must come before `const async`: `pub const async`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-76437-const.rs b/src/test/ui/parser/issues/issue-76437-const.rs
new file mode 100644
index 000000000..d3815a523
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-const.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+mod t {
+ const pub fn t() {}
+ //~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+ //~| HELP visibility `pub` must come before `const`
+}
diff --git a/src/test/ui/parser/issues/issue-76437-const.stderr b/src/test/ui/parser/issues/issue-76437-const.stderr
new file mode 100644
index 000000000..cf80d9a90
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-const.stderr
@@ -0,0 +1,11 @@
+error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+ --> $DIR/issue-76437-const.rs:4:11
+ |
+LL | const pub fn t() {}
+ | ------^^^
+ | | |
+ | | expected one of `async`, `extern`, `fn`, or `unsafe`
+ | help: visibility `pub` must come before `const`: `pub const`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs
new file mode 100644
index 000000000..daa1d1207
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+mod t {
+ unsafe pub(crate) fn t() {}
+ //~^ ERROR expected one of `extern` or `fn`, found keyword `pub`
+ //~| HELP visibility `pub(crate)` must come before `unsafe`
+}
diff --git a/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr
new file mode 100644
index 000000000..fa8f13721
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr
@@ -0,0 +1,11 @@
+error: expected one of `extern` or `fn`, found keyword `pub`
+ --> $DIR/issue-76437-pub-crate-unsafe.rs:4:12
+ |
+LL | unsafe pub(crate) fn t() {}
+ | -------^^^-------
+ | | |
+ | | expected one of `extern` or `fn`
+ | help: visibility `pub(crate)` must come before `unsafe`: `pub(crate) unsafe`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-76437-unsafe.rs b/src/test/ui/parser/issues/issue-76437-unsafe.rs
new file mode 100644
index 000000000..785a79a79
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-unsafe.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+mod t {
+ unsafe pub fn t() {}
+ //~^ ERROR expected one of `extern` or `fn`, found keyword `pub`
+ //~| HELP visibility `pub` must come before `unsafe`
+}
diff --git a/src/test/ui/parser/issues/issue-76437-unsafe.stderr b/src/test/ui/parser/issues/issue-76437-unsafe.stderr
new file mode 100644
index 000000000..c63292ef8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76437-unsafe.stderr
@@ -0,0 +1,11 @@
+error: expected one of `extern` or `fn`, found keyword `pub`
+ --> $DIR/issue-76437-unsafe.rs:4:12
+ |
+LL | unsafe pub fn t() {}
+ | -------^^^
+ | | |
+ | | expected one of `extern` or `fn`
+ | help: visibility `pub` must come before `unsafe`: `pub unsafe`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-76597.fixed b/src/test/ui/parser/issues/issue-76597.fixed
new file mode 100644
index 000000000..2d7a30b83
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76597.fixed
@@ -0,0 +1,11 @@
+// run-rustfix
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+fn f(
+ x: u8,
+ y: u8,
+) {}
+//~^^ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-76597.rs b/src/test/ui/parser/issues/issue-76597.rs
new file mode 100644
index 000000000..521b9c64b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76597.rs
@@ -0,0 +1,11 @@
+// run-rustfix
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+fn f(
+ x: u8
+ y: u8,
+) {}
+//~^^ ERROR: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-76597.stderr b/src/test/ui/parser/issues/issue-76597.stderr
new file mode 100644
index 000000000..50b23329f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-76597.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `y`
+ --> $DIR/issue-76597.rs:7:38
+ |
+LL | ... x: u8
+ | -
+ | |
+ | expected one of 7 possible tokens
+ | help: missing `,`
+LL | ... y: u8,
+ | ^ unexpected token
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-7970b.rs b/src/test/ui/parser/issues/issue-7970b.rs
new file mode 100644
index 000000000..1c4abce39
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-7970b.rs
@@ -0,0 +1,4 @@
+fn main() {}
+
+macro_rules! test {}
+//~^ ERROR unexpected end of macro invocation
diff --git a/src/test/ui/parser/issues/issue-7970b.stderr b/src/test/ui/parser/issues/issue-7970b.stderr
new file mode 100644
index 000000000..a62226a8a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-7970b.stderr
@@ -0,0 +1,8 @@
+error: unexpected end of macro invocation
+ --> $DIR/issue-7970b.rs:3:1
+ |
+LL | macro_rules! test {}
+ | ^^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-81806.rs b/src/test/ui/parser/issues/issue-81806.rs
new file mode 100644
index 000000000..ca86788df
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-81806.rs
@@ -0,0 +1,5 @@
+trait T { const
+impl //~ ERROR: expected identifier, found keyword `impl`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-81806.stderr b/src/test/ui/parser/issues/issue-81806.stderr
new file mode 100644
index 000000000..40873388d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-81806.stderr
@@ -0,0 +1,17 @@
+error: expected identifier, found keyword `impl`
+ --> $DIR/issue-81806.rs:2:1
+ |
+LL | trait T { const
+ | - while parsing this item list starting here
+LL | impl
+ | ^^^^ expected identifier, found keyword
+LL | }
+ | - the item list ends here
+ |
+help: escape `impl` to use it as an identifier
+ |
+LL | r#impl
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-83639.rs b/src/test/ui/parser/issues/issue-83639.rs
new file mode 100644
index 000000000..6ddbedfa0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-83639.rs
@@ -0,0 +1,6 @@
+// check-fail
+// ignore-tidy-tab
+
+fn main() {
+ """ " //~ ERROR
+}
diff --git a/src/test/ui/parser/issues/issue-83639.stderr b/src/test/ui/parser/issues/issue-83639.stderr
new file mode 100644
index 000000000..4c10df191
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-83639.stderr
@@ -0,0 +1,8 @@
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `" "`
+ --> $DIR/issue-83639.rs:5:7
+ |
+LL | """ "
+ | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-84104.rs b/src/test/ui/parser/issues/issue-84104.rs
new file mode 100644
index 000000000..998949b94
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84104.rs
@@ -0,0 +1,3 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: expected one of
+#[i=i::<ښܖ<
diff --git a/src/test/ui/parser/issues/issue-84104.stderr b/src/test/ui/parser/issues/issue-84104.stderr
new file mode 100644
index 000000000..aff31f2c9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84104.stderr
@@ -0,0 +1,16 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-84104.rs:3:13
+ |
+LL | #[i=i::<ښܖ<
+ | - ^
+ | |
+ | unclosed delimiter
+
+error: expected one of `>`, a const expression, lifetime, or type, found `]`
+ --> $DIR/issue-84104.rs:3:13
+ |
+LL | #[i=i::<ښܖ<
+ | ^ expected one of `>`, a const expression, lifetime, or type
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-84117.rs b/src/test/ui/parser/issues/issue-84117.rs
new file mode 100644
index 000000000..c9ebf1335
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84117.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ //~^ ERROR expected one of `>`, a const expression
+ //~| ERROR expected one of `>`, a const expression, lifetime, or type, found `}`
+ //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ //~| ERROR expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+}
+//~^ ERROR expected one of `,` or `>`, found `}`
diff --git a/src/test/ui/parser/issues/issue-84117.stderr b/src/test/ui/parser/issues/issue-84117.stderr
new file mode 100644
index 000000000..237bc11bd
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84117.stderr
@@ -0,0 +1,72 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `}`
+ --> $DIR/issue-84117.rs:2:67
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ | ----------- ^ expected one of `>`, a const expression, lifetime, or type
+ | |
+ | while parsing the type for `inner_local`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str>, }
+ | +
+help: use `=` if you meant to assign
+ |
+LL | let outer_local:e_outer<&str, { let inner_local =e_inner<&str, }
+ | ~
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ --> $DIR/issue-84117.rs:2:65
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ | ^ expected one of 8 possible tokens
+
+error: expected one of `,` or `>`, found `}`
+ --> $DIR/issue-84117.rs:8:1
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ | ----------- while parsing the type for `outer_local` - expected one of `,` or `>`
+...
+LL | }
+ | ^ unexpected token
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }>
+ | +
+help: use `=` if you meant to assign
+ |
+LL | let outer_local =e_outer<&str, { let inner_local:e_inner<&str, }
+ | ~
+
+error: expected one of `>`, a const expression, lifetime, or type, found `}`
+ --> $DIR/issue-84117.rs:2:67
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ | ----------- ^ expected one of `>`, a const expression, lifetime, or type
+ | |
+ | while parsing the type for `inner_local`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str>, }
+ | +
+help: use `=` if you meant to assign
+ |
+LL | let outer_local:e_outer<&str, { let inner_local =e_inner<&str, }
+ | ~
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ --> $DIR/issue-84117.rs:2:65
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ | ^ expected one of 8 possible tokens
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ --> $DIR/issue-84117.rs:2:33
+ |
+LL | let outer_local:e_outer<&str, { let inner_local:e_inner<&str, }
+ | ^ expected one of 8 possible tokens
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-84148-1.rs b/src/test/ui/parser/issues/issue-84148-1.rs
new file mode 100644
index 000000000..9fa8086c2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84148-1.rs
@@ -0,0 +1,3 @@
+fn f(t:for<>t?)
+//~^ ERROR: expected one of
+//~| ERROR: invalid `?` in type
diff --git a/src/test/ui/parser/issues/issue-84148-1.stderr b/src/test/ui/parser/issues/issue-84148-1.stderr
new file mode 100644
index 000000000..9261067c2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84148-1.stderr
@@ -0,0 +1,19 @@
+error: invalid `?` in type
+ --> $DIR/issue-84148-1.rs:1:14
+ |
+LL | fn f(t:for<>t?)
+ | ^ `?` is only allowed on expressions, not types
+ |
+help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
+ |
+LL | fn f(t:Option<for<>t>)
+ | +++++++ ~
+
+error: expected one of `->`, `where`, or `{`, found `<eof>`
+ --> $DIR/issue-84148-1.rs:1:15
+ |
+LL | fn f(t:for<>t?)
+ | ^ expected one of `->`, `where`, or `{`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-84148-2.rs b/src/test/ui/parser/issues/issue-84148-2.rs
new file mode 100644
index 000000000..2f6a7facf
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84148-2.rs
@@ -0,0 +1,3 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: invalid `?` in type
+fn f(t:for<>t?
diff --git a/src/test/ui/parser/issues/issue-84148-2.stderr b/src/test/ui/parser/issues/issue-84148-2.stderr
new file mode 100644
index 000000000..71d543f9b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-84148-2.stderr
@@ -0,0 +1,27 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-84148-2.rs:3:16
+ |
+LL | fn f(t:for<>t?
+ | - ^
+ | |
+ | unclosed delimiter
+
+error: invalid `?` in type
+ --> $DIR/issue-84148-2.rs:3:14
+ |
+LL | fn f(t:for<>t?
+ | ^ `?` is only allowed on expressions, not types
+ |
+help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
+ |
+LL | fn f(t:Option<for<>t>
+ | +++++++ ~
+
+error: expected one of `->`, `where`, or `{`, found `<eof>`
+ --> $DIR/issue-84148-2.rs:3:16
+ |
+LL | fn f(t:for<>t?
+ | ^ expected one of `->`, `where`, or `{`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-8537.rs b/src/test/ui/parser/issues/issue-8537.rs
new file mode 100644
index 000000000..9d0cbce6c
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-8537.rs
@@ -0,0 +1,5 @@
+pub extern
+ "invalid-ab_isize" //~ ERROR invalid ABI
+fn foo() {}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-8537.stderr b/src/test/ui/parser/issues/issue-8537.stderr
new file mode 100644
index 000000000..505d830ef
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-8537.stderr
@@ -0,0 +1,11 @@
+error[E0703]: invalid ABI: found `invalid-ab_isize`
+ --> $DIR/issue-8537.rs:2:3
+ |
+LL | "invalid-ab_isize"
+ | ^^^^^^^^^^^^^^^^^^ invalid ABI
+ |
+ = help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted, rust-cold
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0703`.
diff --git a/src/test/ui/parser/issues/issue-86895.rs b/src/test/ui/parser/issues/issue-86895.rs
new file mode 100644
index 000000000..4cd098431
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-86895.rs
@@ -0,0 +1,3 @@
+const pub () {}
+//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`
+pub fn main() {}
diff --git a/src/test/ui/parser/issues/issue-86895.stderr b/src/test/ui/parser/issues/issue-86895.stderr
new file mode 100644
index 000000000..575d857c0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-86895.stderr
@@ -0,0 +1,8 @@
+error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+ --> $DIR/issue-86895.rs:1:7
+ |
+LL | const pub () {}
+ | ^^^ expected one of `async`, `extern`, `fn`, or `unsafe`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-87086-colon-path-sep.rs b/src/test/ui/parser/issues/issue-87086-colon-path-sep.rs
new file mode 100644
index 000000000..0b7b67496
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87086-colon-path-sep.rs
@@ -0,0 +1,79 @@
+// Tests that a suggestion is issued if the user wrote a colon instead of
+// a path separator in a match arm.
+
+mod qux {
+ pub enum Foo {
+ Bar,
+ Baz,
+ }
+}
+
+use qux::Foo;
+
+fn f() -> Foo { Foo::Bar }
+
+fn g1() {
+ match f() {
+ Foo:Bar => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ _ => {}
+ }
+ match f() {
+ qux::Foo:Bar => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ _ => {}
+ }
+ match f() {
+ qux:Foo::Baz => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ _ => {}
+ }
+ match f() {
+ qux: Foo::Baz if true => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ _ => {}
+ }
+ if let Foo:Bar = f() {
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ }
+}
+
+fn g1_neg() {
+ match f() {
+ ref qux: Foo::Baz => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ _ => {}
+ }
+}
+
+fn g2_neg() {
+ match f() {
+ mut qux: Foo::Baz => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ _ => {}
+ }
+}
+
+fn main() {
+ let myfoo = Foo::Bar;
+ match myfoo {
+ Foo::Bar => {}
+ Foo:Bar::Baz => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ //~| ERROR: failed to resolve: `Bar` is a variant, not a module
+ }
+ match myfoo {
+ Foo::Bar => {}
+ Foo:Bar => {}
+ //~^ ERROR: expected one of
+ //~| HELP: maybe write a path separator here
+ }
+}
diff --git a/src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr b/src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr
new file mode 100644
index 000000000..2050a16be
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87086-colon-path-sep.stderr
@@ -0,0 +1,90 @@
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:17:12
+ |
+LL | Foo:Bar => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `{`, or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:23:17
+ |
+LL | qux::Foo:Bar => {}
+ | ^
+ | |
+ | expected one of 8 possible tokens
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:29:12
+ |
+LL | qux:Foo::Baz => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:35:12
+ |
+LL | qux: Foo::Baz if true => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:40:15
+ |
+LL | if let Foo:Bar = f() {
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:48:16
+ |
+LL | ref qux: Foo::Baz => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:57:16
+ |
+LL | mut qux: Foo::Baz => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:68:12
+ |
+LL | Foo:Bar::Baz => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error: expected one of `@` or `|`, found `:`
+ --> $DIR/issue-87086-colon-path-sep.rs:75:12
+ |
+LL | Foo:Bar => {}
+ | ^
+ | |
+ | expected one of `@` or `|`
+ | help: maybe write a path separator here: `::`
+
+error[E0433]: failed to resolve: `Bar` is a variant, not a module
+ --> $DIR/issue-87086-colon-path-sep.rs:68:13
+ |
+LL | Foo:Bar::Baz => {}
+ | ^^^ `Bar` is a variant, not a module
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed b/src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed
new file mode 100644
index 000000000..53f071db7
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87197-missing-semicolon.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+// Parser should know when a semicolon is missing.
+// https://github.com/rust-lang/rust/issues/87197
+
+fn main() {
+ let x = 100; //~ ERROR: expected `;`
+ println!("{}", x); //~ ERROR: expected `;`
+ let y = 200; //~ ERROR: expected `;`
+ println!("{}", y);
+}
diff --git a/src/test/ui/parser/issues/issue-87197-missing-semicolon.rs b/src/test/ui/parser/issues/issue-87197-missing-semicolon.rs
new file mode 100644
index 000000000..db0edf452
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87197-missing-semicolon.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+// Parser should know when a semicolon is missing.
+// https://github.com/rust-lang/rust/issues/87197
+
+fn main() {
+ let x = 100 //~ ERROR: expected `;`
+ println!("{}", x) //~ ERROR: expected `;`
+ let y = 200 //~ ERROR: expected `;`
+ println!("{}", y);
+}
diff --git a/src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr b/src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr
new file mode 100644
index 000000000..57772de1e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87197-missing-semicolon.stderr
@@ -0,0 +1,26 @@
+error: expected `;`, found `println`
+ --> $DIR/issue-87197-missing-semicolon.rs:6:16
+ |
+LL | let x = 100
+ | ^ help: add `;` here
+LL | println!("{}", x)
+ | ------- unexpected token
+
+error: expected `;`, found keyword `let`
+ --> $DIR/issue-87197-missing-semicolon.rs:7:22
+ |
+LL | println!("{}", x)
+ | ^ help: add `;` here
+LL | let y = 200
+ | --- unexpected token
+
+error: expected `;`, found `println`
+ --> $DIR/issue-87197-missing-semicolon.rs:8:16
+ |
+LL | let y = 200
+ | ^ help: add `;` here
+LL | println!("{}", y);
+ | ------- unexpected token
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
new file mode 100644
index 000000000..df0cd5439
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
@@ -0,0 +1,9 @@
+// edition:2018
+
+// Test that even when `const` is already present, the proposed fix is to remove the second `const`
+
+const async const fn test() {}
+//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
+//~| NOTE expected one of `extern`, `fn`, or `unsafe`
+//~| HELP `const` already used earlier, remove this one
+//~| NOTE `const` first seen here
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr
new file mode 100644
index 000000000..977c6ebfe
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr
@@ -0,0 +1,17 @@
+error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
+ --> $DIR/const-async-const.rs:5:13
+ |
+LL | const async const fn test() {}
+ | ^^^^^
+ | |
+ | expected one of `extern`, `fn`, or `unsafe`
+ | help: `const` already used earlier, remove this one
+ |
+note: `const` first seen here
+ --> $DIR/const-async-const.rs:5:1
+ |
+LL | const async const fn test() {}
+ | ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
new file mode 100644
index 000000000..bbebc99e9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+// There is an order to respect for keywords before a function:
+// `<visibility>, const, async, unsafe, extern, "<ABI>"`
+//
+// This test ensures the compiler is helpful about them being misplaced.
+// Visibilities are tested elsewhere.
+
+async unsafe const fn test() {}
+//~^ ERROR expected one of `extern` or `fn`, found keyword `const`
+//~| NOTE expected one of `extern` or `fn`
+//~| HELP `const` must come before `async unsafe`
+//~| SUGGESTION const async unsafe
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr
new file mode 100644
index 000000000..f455caba1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr
@@ -0,0 +1,13 @@
+error: expected one of `extern` or `fn`, found keyword `const`
+ --> $DIR/several-kw-jump.rs:9:14
+ |
+LL | async unsafe const fn test() {}
+ | -------------^^^^^
+ | | |
+ | | expected one of `extern` or `fn`
+ | help: `const` must come before `async unsafe`: `const async unsafe`
+ |
+ = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs
new file mode 100644
index 000000000..4ff4cf5c8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+// There is an order to respect for keywords before a function:
+// `<visibility>, const, async, unsafe, extern, "<ABI>"`
+//
+// This test ensures the compiler is helpful about them being misplaced.
+// Visibilities are tested elsewhere.
+
+unsafe async fn test() {}
+//~^ ERROR expected one of `extern` or `fn`, found keyword `async`
+//~| NOTE expected one of `extern` or `fn`
+//~| HELP `async` must come before `unsafe`
+//~| SUGGESTION async unsafe
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr
new file mode 100644
index 000000000..e9eb14bf0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr
@@ -0,0 +1,13 @@
+error: expected one of `extern` or `fn`, found keyword `async`
+ --> $DIR/wrong-async.rs:9:8
+ |
+LL | unsafe async fn test() {}
+ | -------^^^^^
+ | | |
+ | | expected one of `extern` or `fn`
+ | help: `async` must come before `unsafe`: `async unsafe`
+ |
+ = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs
new file mode 100644
index 000000000..2f5fbc513
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+// There is an order to respect for keywords before a function:
+// `<visibility>, const, async, unsafe, extern, "<ABI>"`
+//
+// This test ensures the compiler is helpful about them being misplaced.
+// Visibilities are tested elsewhere.
+
+unsafe const fn test() {}
+//~^ ERROR expected one of `extern` or `fn`, found keyword `const`
+//~| NOTE expected one of `extern` or `fn`
+//~| HELP `const` must come before `unsafe`
+//~| SUGGESTION const unsafe
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr
new file mode 100644
index 000000000..0d2bc3472
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr
@@ -0,0 +1,13 @@
+error: expected one of `extern` or `fn`, found keyword `const`
+ --> $DIR/wrong-const.rs:9:8
+ |
+LL | unsafe const fn test() {}
+ | -------^^^^^
+ | | |
+ | | expected one of `extern` or `fn`
+ | help: `const` must come before `unsafe`: `const unsafe`
+ |
+ = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
new file mode 100644
index 000000000..df2412e3e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+// There is an order to respect for keywords before a function:
+// `<visibility>, const, async, unsafe, extern, "<ABI>"`
+//
+// This test ensures the compiler is helpful about them being misplaced.
+// Visibilities are tested elsewhere.
+
+extern unsafe fn test() {}
+//~^ ERROR expected `fn`, found keyword `unsafe`
+//~| NOTE expected `fn`
+//~| HELP `unsafe` must come before `extern`
+//~| SUGGESTION unsafe extern
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
new file mode 100644
index 000000000..4224713cc
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
@@ -0,0 +1,13 @@
+error: expected `fn`, found keyword `unsafe`
+ --> $DIR/wrong-unsafe.rs:9:8
+ |
+LL | extern unsafe fn test() {}
+ | -------^^^^^^
+ | | |
+ | | expected `fn`
+ | help: `unsafe` must come before `extern`: `unsafe extern`
+ |
+ = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-87635.rs b/src/test/ui/parser/issues/issue-87635.rs
new file mode 100644
index 000000000..f70a87fb0
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87635.rs
@@ -0,0 +1,9 @@
+struct Foo {}
+
+impl Foo {
+ pub fn bar()
+ //~^ ERROR: associated function in `impl` without body
+}
+//~^ERROR expected one of `->`, `where`, or `{`, found `}`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-87635.stderr b/src/test/ui/parser/issues/issue-87635.stderr
new file mode 100644
index 000000000..1d459f1b9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87635.stderr
@@ -0,0 +1,19 @@
+error: expected one of `->`, `where`, or `{`, found `}`
+ --> $DIR/issue-87635.rs:6:1
+ |
+LL | pub fn bar()
+ | --- - expected one of `->`, `where`, or `{`
+ | |
+ | while parsing this `fn`
+LL |
+LL | }
+ | ^ unexpected token
+
+error: associated function in `impl` without body
+ --> $DIR/issue-87635.rs:4:5
+ |
+LL | pub fn bar()
+ | ^^^^^^^^^^^^- help: provide a definition for the function: `{ <body> }`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-87812-path.rs b/src/test/ui/parser/issues/issue-87812-path.rs
new file mode 100644
index 000000000..b88780876
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87812-path.rs
@@ -0,0 +1,11 @@
+macro_rules! foo {
+ ( $f:path ) => {{
+ let _: usize = $f; //~ERROR
+ }};
+}
+
+struct Baz;
+
+fn main() {
+ foo!(Baz);
+}
diff --git a/src/test/ui/parser/issues/issue-87812-path.stderr b/src/test/ui/parser/issues/issue-87812-path.stderr
new file mode 100644
index 000000000..f8ee05175
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87812-path.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-87812-path.rs:3:24
+ |
+LL | let _: usize = $f;
+ | ----- ^^ expected `usize`, found struct `Baz`
+ | |
+ | expected due to this
+...
+LL | foo!(Baz);
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issues/issue-87812.rs b/src/test/ui/parser/issues/issue-87812.rs
new file mode 100644
index 000000000..0ba87b995
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87812.rs
@@ -0,0 +1,13 @@
+#![deny(break_with_label_and_loop)]
+
+macro_rules! foo {
+ ( $f:block ) => {
+ '_l: loop {
+ break '_l $f; //~ERROR
+ }
+ };
+}
+
+fn main() {
+ let x = foo!({ 3 });
+}
diff --git a/src/test/ui/parser/issues/issue-87812.stderr b/src/test/ui/parser/issues/issue-87812.stderr
new file mode 100644
index 000000000..d61ee23a5
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-87812.stderr
@@ -0,0 +1,22 @@
+error: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression
+ --> $DIR/issue-87812.rs:6:13
+ |
+LL | break '_l $f;
+ | ^^^^^^^^^^^^
+...
+LL | let x = foo!({ 3 });
+ | ----------- in this macro invocation
+ |
+note: the lint level is defined here
+ --> $DIR/issue-87812.rs:1:9
+ |
+LL | #![deny(break_with_label_and_loop)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: wrap this expression in parentheses
+ |
+LL | break '_l ($f);
+ | + +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-88276-unary-plus.fixed b/src/test/ui/parser/issues/issue-88276-unary-plus.fixed
new file mode 100644
index 000000000..25b7c340f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88276-unary-plus.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+#[allow(unused_parens)]
+fn main() {
+ let _ = 1; //~ ERROR leading `+` is not supported
+ let _ = (1.0 + 2.0) * 3.0; //~ ERROR leading `+` is not supported
+ //~| ERROR leading `+` is not supported
+ let _ = [3, 4+6]; //~ ERROR leading `+` is not supported
+}
diff --git a/src/test/ui/parser/issues/issue-88276-unary-plus.rs b/src/test/ui/parser/issues/issue-88276-unary-plus.rs
new file mode 100644
index 000000000..11b2e9d60
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88276-unary-plus.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+#[allow(unused_parens)]
+fn main() {
+ let _ = +1; //~ ERROR leading `+` is not supported
+ let _ = (1.0 + +2.0) * +3.0; //~ ERROR leading `+` is not supported
+ //~| ERROR leading `+` is not supported
+ let _ = [+3, 4+6]; //~ ERROR leading `+` is not supported
+}
diff --git a/src/test/ui/parser/issues/issue-88276-unary-plus.stderr b/src/test/ui/parser/issues/issue-88276-unary-plus.stderr
new file mode 100644
index 000000000..363e08201
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88276-unary-plus.stderr
@@ -0,0 +1,50 @@
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:4:13
+ |
+LL | let _ = +1;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = +1;
+LL + let _ = 1;
+ |
+
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:5:20
+ |
+LL | let _ = (1.0 + +2.0) * +3.0;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = (1.0 + +2.0) * +3.0;
+LL + let _ = (1.0 + 2.0) * +3.0;
+ |
+
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:5:28
+ |
+LL | let _ = (1.0 + +2.0) * +3.0;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = (1.0 + +2.0) * +3.0;
+LL + let _ = (1.0 + +2.0) * 3.0;
+ |
+
+error: leading `+` is not supported
+ --> $DIR/issue-88276-unary-plus.rs:7:14
+ |
+LL | let _ = [+3, 4+6];
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - let _ = [+3, 4+6];
+LL + let _ = [3, 4+6];
+ |
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-88583-union-as-ident.rs b/src/test/ui/parser/issues/issue-88583-union-as-ident.rs
new file mode 100644
index 000000000..b3d66d46b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88583-union-as-ident.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![allow(non_camel_case_types)]
+
+struct union;
+
+impl union {
+ pub fn new() -> Self {
+ union { }
+ }
+}
+
+fn main() {
+ let _u = union::new();
+}
diff --git a/src/test/ui/parser/issues/issue-88770.rs b/src/test/ui/parser/issues/issue-88770.rs
new file mode 100644
index 000000000..bb69951c7
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88770.rs
@@ -0,0 +1,11 @@
+// Regression test for the ICE described in #88770.
+
+// error-pattern:this file contains an unclosed delimiter
+// error-pattern:expected one of
+// error-pattern:missing `in` in `for` loop
+// error-pattern:expected one of `!`, `)`, `,`, `.`, `::`, `;`, `?`, `{`, or an operator, found `e`
+
+fn m(){print!("",(c for&g
+u
+e
+e
diff --git a/src/test/ui/parser/issues/issue-88770.stderr b/src/test/ui/parser/issues/issue-88770.stderr
new file mode 100644
index 000000000..4e3a21613
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88770.stderr
@@ -0,0 +1,60 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-88770.rs:11:3
+ |
+LL | fn m(){print!("",(c for&g
+ | - - - unclosed delimiter
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+...
+LL | e
+ | ^
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-88770.rs:11:3
+ |
+LL | fn m(){print!("",(c for&g
+ | - - - unclosed delimiter
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+...
+LL | e
+ | ^
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-88770.rs:11:3
+ |
+LL | fn m(){print!("",(c for&g
+ | - - - unclosed delimiter
+ | | |
+ | | unclosed delimiter
+ | unclosed delimiter
+...
+LL | e
+ | ^
+
+error: missing `in` in `for` loop
+ --> $DIR/issue-88770.rs:8:26
+ |
+LL | fn m(){print!("",(c for&g
+ | __________________________^
+LL | | u
+ | |_ help: try adding `in` here
+
+error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found keyword `for`
+ --> $DIR/issue-88770.rs:8:21
+ |
+LL | fn m(){print!("",(c for&g
+ | ^^^ expected one of 8 possible tokens
+
+error: expected one of `!`, `)`, `,`, `.`, `::`, `;`, `?`, `{`, or an operator, found `e`
+ --> $DIR/issue-88770.rs:11:1
+ |
+LL | e
+ | - expected one of 9 possible tokens
+LL | e
+ | ^ unexpected token
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-88818.rs b/src/test/ui/parser/issues/issue-88818.rs
new file mode 100644
index 000000000..b9233ca83
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88818.rs
@@ -0,0 +1,10 @@
+// Regression test for #88818 (improve error message for missing trait
+// in `impl for X`).
+
+struct S { }
+impl for S { }
+//~^ ERROR: missing trait in a trait impl
+//~| HELP: add a trait here
+//~| HELP: for an inherent impl, drop this `for`
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-88818.stderr b/src/test/ui/parser/issues/issue-88818.stderr
new file mode 100644
index 000000000..6e624c5a2
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-88818.stderr
@@ -0,0 +1,18 @@
+error: missing trait in a trait impl
+ --> $DIR/issue-88818.rs:5:5
+ |
+LL | impl for S { }
+ | ^
+ |
+help: add a trait here
+ |
+LL | impl Trait for S { }
+ | +++++
+help: for an inherent impl, drop this `for`
+ |
+LL - impl for S { }
+LL + impl S { }
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-89388.rs b/src/test/ui/parser/issues/issue-89388.rs
new file mode 100644
index 000000000..9153c071e
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89388.rs
@@ -0,0 +1,7 @@
+// Regression test for #89388.
+
+fn main() {
+ let option: Option<&[u8]> = Some(b"...");
+ let _ = option.map([_]::to_vec);
+ //~^ ERROR: missing angle brackets in associated item path
+}
diff --git a/src/test/ui/parser/issues/issue-89388.stderr b/src/test/ui/parser/issues/issue-89388.stderr
new file mode 100644
index 000000000..cf28bef0f
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89388.stderr
@@ -0,0 +1,8 @@
+error: missing angle brackets in associated item path
+ --> $DIR/issue-89388.rs:5:24
+ |
+LL | let _ = option.map([_]::to_vec);
+ | ^^^^^^^^^^^ help: try: `<[_]>::to_vec`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-89396.fixed b/src/test/ui/parser/issues/issue-89396.fixed
new file mode 100644
index 000000000..823ad8cd1
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89396.fixed
@@ -0,0 +1,16 @@
+// Regression test for issue #89396: Try to recover from a
+// `=>` -> `=` or `->` typo in a match arm.
+
+// run-rustfix
+
+fn main() {
+ let opt = Some(42);
+ let _ = match opt {
+ Some(_) => true,
+ //~^ ERROR: expected one of
+ //~| HELP: try using a fat arrow here
+ None => false,
+ //~^ ERROR: expected one of
+ //~| HELP: try using a fat arrow here
+ };
+}
diff --git a/src/test/ui/parser/issues/issue-89396.rs b/src/test/ui/parser/issues/issue-89396.rs
new file mode 100644
index 000000000..f1d9efa52
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89396.rs
@@ -0,0 +1,16 @@
+// Regression test for issue #89396: Try to recover from a
+// `=>` -> `=` or `->` typo in a match arm.
+
+// run-rustfix
+
+fn main() {
+ let opt = Some(42);
+ let _ = match opt {
+ Some(_) = true,
+ //~^ ERROR: expected one of
+ //~| HELP: try using a fat arrow here
+ None -> false,
+ //~^ ERROR: expected one of
+ //~| HELP: try using a fat arrow here
+ };
+}
diff --git a/src/test/ui/parser/issues/issue-89396.stderr b/src/test/ui/parser/issues/issue-89396.stderr
new file mode 100644
index 000000000..504420574
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89396.stderr
@@ -0,0 +1,20 @@
+error: expected one of `=>`, `if`, or `|`, found `=`
+ --> $DIR/issue-89396.rs:9:17
+ |
+LL | Some(_) = true,
+ | ^
+ | |
+ | expected one of `=>`, `if`, or `|`
+ | help: try using a fat arrow here: `=>`
+
+error: expected one of `=>`, `@`, `if`, or `|`, found `->`
+ --> $DIR/issue-89396.rs:12:14
+ |
+LL | None -> false,
+ | ^^
+ | |
+ | expected one of `=>`, `@`, `if`, or `|`
+ | help: try using a fat arrow here: `=>`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-89574.rs b/src/test/ui/parser/issues/issue-89574.rs
new file mode 100644
index 000000000..0a477f1aa
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89574.rs
@@ -0,0 +1,4 @@
+fn main() {
+ const EMPTY_ARRAY = [];
+ //~^ missing type for `const` item
+}
diff --git a/src/test/ui/parser/issues/issue-89574.stderr b/src/test/ui/parser/issues/issue-89574.stderr
new file mode 100644
index 000000000..cbee3d351
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89574.stderr
@@ -0,0 +1,8 @@
+error: missing type for `const` item
+ --> $DIR/issue-89574.rs:2:11
+ |
+LL | const EMPTY_ARRAY = [];
+ | ^^^^^^^^^^^ help: provide a type for the item: `EMPTY_ARRAY: <type>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs
new file mode 100644
index 000000000..fe67d9822
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs
@@ -0,0 +1,15 @@
+// aux-build:issue-89971-outer-attr-following-inner-attr-ice.rs
+
+#[macro_use]
+extern crate issue_89971_outer_attr_following_inner_attr_ice;
+
+fn main() {
+ Mew();
+ X {};
+}
+
+#![deny(missing_docs)]
+//~^ ERROR an inner attribute is not permitted in this context
+#[derive(ICE)]
+#[deny(missing_docs)]
+struct Mew();
diff --git a/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr
new file mode 100644
index 000000000..a5ee24445
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr
@@ -0,0 +1,18 @@
+error: an inner attribute is not permitted in this context
+ --> $DIR/issue-89971-outer-attr-following-inner-attr-ice.rs:11:1
+ |
+LL | #![deny(missing_docs)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | struct Mew();
+ | ------------- the inner attribute doesn't annotate this struct
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+help: to annotate the struct, change the attribute from inner to outer style
+ |
+LL - #![deny(missing_docs)]
+LL + #[deny(missing_docs)]
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-90993.rs b/src/test/ui/parser/issues/issue-90993.rs
new file mode 100644
index 000000000..40e6fc748
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-90993.rs
@@ -0,0 +1,6 @@
+fn main() {
+ ...=.
+ //~^ ERROR: unexpected token: `...`
+ //~| ERROR: unexpected `=` after inclusive range
+ //~| ERROR: expected one of `-`, `;`, `}`, or path, found `.`
+}
diff --git a/src/test/ui/parser/issues/issue-90993.stderr b/src/test/ui/parser/issues/issue-90993.stderr
new file mode 100644
index 000000000..ab6bce410
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-90993.stderr
@@ -0,0 +1,31 @@
+error: unexpected token: `...`
+ --> $DIR/issue-90993.rs:2:5
+ |
+LL | ...=.
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | ..=.
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | ..==.
+ | ~~~
+
+error: unexpected `=` after inclusive range
+ --> $DIR/issue-90993.rs:2:5
+ |
+LL | ...=.
+ | ^^^^ help: use `..=` instead
+ |
+ = note: inclusive ranges end with a single equals sign (`..=`)
+
+error: expected one of `-`, `;`, `}`, or path, found `.`
+ --> $DIR/issue-90993.rs:2:9
+ |
+LL | ...=.
+ | ^ expected one of `-`, `;`, `}`, or path
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-91461.rs b/src/test/ui/parser/issues/issue-91461.rs
new file mode 100644
index 000000000..3e3c411c4
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-91461.rs
@@ -0,0 +1,6 @@
+fn main() {
+ a(_:b:,)
+ //~^ ERROR: expected identifier, found reserved identifier `_`
+ //~| ERROR: expected type, found `,`
+ //~| ERROR: expected type, found `,`
+}
diff --git a/src/test/ui/parser/issues/issue-91461.stderr b/src/test/ui/parser/issues/issue-91461.stderr
new file mode 100644
index 000000000..94fcf1721
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-91461.stderr
@@ -0,0 +1,31 @@
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/issue-91461.rs:2:7
+ |
+LL | a(_:b:,)
+ | ^ expected identifier, found reserved identifier
+
+error: expected type, found `,`
+ --> $DIR/issue-91461.rs:2:11
+ |
+LL | a(_:b:,)
+ | - -^ expected type
+ | | |
+ | | tried to parse a type due to this type ascription
+ | while parsing this struct
+ |
+ = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+ = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+
+error: expected type, found `,`
+ --> $DIR/issue-91461.rs:2:11
+ |
+LL | a(_:b:,)
+ | -^ expected type
+ | |
+ | tried to parse a type due to this type ascription
+ |
+ = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+ = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-93282.rs b/src/test/ui/parser/issues/issue-93282.rs
new file mode 100644
index 000000000..261fcb5f9
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-93282.rs
@@ -0,0 +1,15 @@
+fn main() {
+ f<'a,>
+ //~^ ERROR expected
+ //~| ERROR expected
+}
+
+fn bar(a: usize, b: usize) -> usize {
+ a + b
+}
+
+fn foo() {
+ let x = 1;
+ bar('y, x);
+ //~^ ERROR expected
+}
diff --git a/src/test/ui/parser/issues/issue-93282.stderr b/src/test/ui/parser/issues/issue-93282.stderr
new file mode 100644
index 000000000..ee554784b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-93282.stderr
@@ -0,0 +1,25 @@
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/issue-93282.rs:2:9
+ |
+LL | f<'a,>
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+
+error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `}`, or an operator, found `,`
+ --> $DIR/issue-93282.rs:2:9
+ |
+LL | f<'a,>
+ | ^ expected one of 9 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | f::<'a,>
+ | ++
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/issue-93282.rs:13:11
+ |
+LL | bar('y, x);
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/issues/issue-93867.rs b/src/test/ui/parser/issues/issue-93867.rs
new file mode 100644
index 000000000..507447923
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-93867.rs
@@ -0,0 +1,10 @@
+pub struct Entry<'a, K, V> {
+ k: &'a mut K,
+ v: V,
+}
+
+pub fn entry<'a, K, V>() -> Entry<'a K, V> {
+// ^ missing comma
+//~^^ expected one of `,` or `>`, found `K`
+ unimplemented!()
+}
diff --git a/src/test/ui/parser/issues/issue-93867.stderr b/src/test/ui/parser/issues/issue-93867.stderr
new file mode 100644
index 000000000..ee0cb4efd
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-93867.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,` or `>`, found `K`
+ --> $DIR/issue-93867.rs:6:38
+ |
+LL | pub fn entry<'a, K, V>() -> Entry<'a K, V> {
+ | ^ expected one of `,` or `>`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | pub fn entry<'a, K, V>() -> Entry<'a> K, V> {
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-94340.rs b/src/test/ui/parser/issues/issue-94340.rs
new file mode 100644
index 000000000..d0fb84a68
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-94340.rs
@@ -0,0 +1,8 @@
+// Make sure that unexpected inner attributes are not labeled as outer ones in diagnostics when
+// trying to parse an item and that they are subsequently ignored not triggering confusing extra
+// diagnostics like "expected item after attributes" which is not true for `include!` which can
+// include empty files.
+
+include!("auxiliary/issue-94340-inc.rs");
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-94340.stderr b/src/test/ui/parser/issues/issue-94340.stderr
new file mode 100644
index 000000000..9fd7c38a8
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-94340.stderr
@@ -0,0 +1,20 @@
+error: an inner attribute is not permitted in this context
+ --> $DIR/auxiliary/issue-94340-inc.rs:2:1
+ |
+LL | #![deny(rust_2018_idioms)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/auxiliary/issue-94340-inc.rs:3:1
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/item-free-const-no-body-semantic-fail.rs b/src/test/ui/parser/item-free-const-no-body-semantic-fail.rs
new file mode 100644
index 000000000..613b3c985
--- /dev/null
+++ b/src/test/ui/parser/item-free-const-no-body-semantic-fail.rs
@@ -0,0 +1,7 @@
+// Semantically, a free `const` item cannot omit its body.
+
+fn main() {}
+
+const A: u8; //~ ERROR free constant item without body
+const B; //~ ERROR free constant item without body
+//~^ ERROR missing type for `const` item
diff --git a/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr b/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr
new file mode 100644
index 000000000..c340e958e
--- /dev/null
+++ b/src/test/ui/parser/item-free-const-no-body-semantic-fail.stderr
@@ -0,0 +1,24 @@
+error: free constant item without body
+ --> $DIR/item-free-const-no-body-semantic-fail.rs:5:1
+ |
+LL | const A: u8;
+ | ^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error: free constant item without body
+ --> $DIR/item-free-const-no-body-semantic-fail.rs:6:1
+ |
+LL | const B;
+ | ^^^^^^^-
+ | |
+ | help: provide a definition for the constant: `= <expr>;`
+
+error: missing type for `const` item
+ --> $DIR/item-free-const-no-body-semantic-fail.rs:6:7
+ |
+LL | const B;
+ | ^ help: provide a type for the item: `B: <type>`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs b/src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs
new file mode 100644
index 000000000..acfdd3c36
--- /dev/null
+++ b/src/test/ui/parser/item-free-const-no-body-syntactic-pass.rs
@@ -0,0 +1,8 @@
+// Syntactically, a free `const` item can omit its body.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+const X: u8;
diff --git a/src/test/ui/parser/item-free-static-no-body-semantic-fail.rs b/src/test/ui/parser/item-free-static-no-body-semantic-fail.rs
new file mode 100644
index 000000000..780479e3d
--- /dev/null
+++ b/src/test/ui/parser/item-free-static-no-body-semantic-fail.rs
@@ -0,0 +1,11 @@
+// Semantically, a free `static` item cannot omit its body.
+
+fn main() {}
+
+static A: u8; //~ ERROR free static item without body
+static B; //~ ERROR free static item without body
+//~^ ERROR missing type for `static` item
+
+static mut C: u8; //~ ERROR free static item without body
+static mut D; //~ ERROR free static item without body
+//~^ ERROR missing type for `static mut` item
diff --git a/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr b/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr
new file mode 100644
index 000000000..4d542b798
--- /dev/null
+++ b/src/test/ui/parser/item-free-static-no-body-semantic-fail.stderr
@@ -0,0 +1,46 @@
+error: free static item without body
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:5:1
+ |
+LL | static A: u8;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the static: `= <expr>;`
+
+error: free static item without body
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:6:1
+ |
+LL | static B;
+ | ^^^^^^^^-
+ | |
+ | help: provide a definition for the static: `= <expr>;`
+
+error: free static item without body
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:9:1
+ |
+LL | static mut C: u8;
+ | ^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the static: `= <expr>;`
+
+error: free static item without body
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:10:1
+ |
+LL | static mut D;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the static: `= <expr>;`
+
+error: missing type for `static` item
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:6:8
+ |
+LL | static B;
+ | ^ help: provide a type for the item: `B: <type>`
+
+error: missing type for `static mut` item
+ --> $DIR/item-free-static-no-body-semantic-fail.rs:10:12
+ |
+LL | static mut D;
+ | ^ help: provide a type for the item: `D: <type>`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs b/src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs
new file mode 100644
index 000000000..db0039204
--- /dev/null
+++ b/src/test/ui/parser/item-free-static-no-body-syntactic-pass.rs
@@ -0,0 +1,8 @@
+// Syntactically, a free `const` item can omit its body.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+static X: u8;
diff --git a/src/test/ui/parser/item-free-type-bounds-semantic-fail.rs b/src/test/ui/parser/item-free-type-bounds-semantic-fail.rs
new file mode 100644
index 000000000..9db4111fb
--- /dev/null
+++ b/src/test/ui/parser/item-free-type-bounds-semantic-fail.rs
@@ -0,0 +1,20 @@
+fn main() {}
+
+fn semantics() {
+ type A: Ord;
+ //~^ ERROR bounds on `type`s in this context have no effect
+ //~| ERROR free type alias without body
+ type B: Ord = u8;
+ //~^ ERROR bounds on `type`s in this context have no effect
+ type C: Ord where 'static: 'static = u8;
+ //~^ ERROR bounds on `type`s in this context have no effect
+ type D<_T>: Ord;
+ //~^ ERROR bounds on `type`s in this context have no effect
+ //~| ERROR free type alias without body
+ type E<_T>: Ord = u8;
+ //~^ ERROR bounds on `type`s in this context have no effect
+ //~| ERROR type parameter `_T` is unused
+ type F<_T>: Ord where 'static: 'static = u8;
+ //~^ ERROR bounds on `type`s in this context have no effect
+ //~| ERROR type parameter `_T` is unused
+}
diff --git a/src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr b/src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr
new file mode 100644
index 000000000..1b0865128
--- /dev/null
+++ b/src/test/ui/parser/item-free-type-bounds-semantic-fail.stderr
@@ -0,0 +1,67 @@
+error: free type alias without body
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:4:5
+ |
+LL | type A: Ord;
+ | ^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error: bounds on `type`s in this context have no effect
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:4:13
+ |
+LL | type A: Ord;
+ | ^^^
+
+error: bounds on `type`s in this context have no effect
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:7:13
+ |
+LL | type B: Ord = u8;
+ | ^^^
+
+error: bounds on `type`s in this context have no effect
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:9:13
+ |
+LL | type C: Ord where 'static: 'static = u8;
+ | ^^^
+
+error: free type alias without body
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:11:5
+ |
+LL | type D<_T>: Ord;
+ | ^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error: bounds on `type`s in this context have no effect
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:11:17
+ |
+LL | type D<_T>: Ord;
+ | ^^^
+
+error: bounds on `type`s in this context have no effect
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:14:17
+ |
+LL | type E<_T>: Ord = u8;
+ | ^^^
+
+error: bounds on `type`s in this context have no effect
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:17:17
+ |
+LL | type F<_T>: Ord where 'static: 'static = u8;
+ | ^^^
+
+error[E0091]: type parameter `_T` is unused
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:14:12
+ |
+LL | type E<_T>: Ord = u8;
+ | ^^ unused type parameter
+
+error[E0091]: type parameter `_T` is unused
+ --> $DIR/item-free-type-bounds-semantic-fail.rs:17:12
+ |
+LL | type F<_T>: Ord where 'static: 'static = u8;
+ | ^^ unused type parameter
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0091`.
diff --git a/src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs b/src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs
new file mode 100644
index 000000000..58fc926d0
--- /dev/null
+++ b/src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+ type A: Ord;
+ type B: Ord = u8;
+ type C: Ord where 'static: 'static = u8;
+ type D<_T>: Ord;
+ type E<_T>: Ord = u8;
+ type F<_T>: Ord where 'static: 'static = u8;
+}
diff --git a/src/test/ui/parser/keyword-abstract.rs b/src/test/ui/parser/keyword-abstract.rs
new file mode 100644
index 000000000..570206575
--- /dev/null
+++ b/src/test/ui/parser/keyword-abstract.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let abstract = (); //~ ERROR expected identifier, found reserved keyword `abstract`
+}
diff --git a/src/test/ui/parser/keyword-abstract.stderr b/src/test/ui/parser/keyword-abstract.stderr
new file mode 100644
index 000000000..b7d1ce7cd
--- /dev/null
+++ b/src/test/ui/parser/keyword-abstract.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found reserved keyword `abstract`
+ --> $DIR/keyword-abstract.rs:2:9
+ |
+LL | let abstract = ();
+ | ^^^^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `abstract` to use it as an identifier
+ |
+LL | let r#abstract = ();
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-as-as-identifier.rs b/src/test/ui/parser/keyword-as-as-identifier.rs
new file mode 100644
index 000000000..cd47c8a39
--- /dev/null
+++ b/src/test/ui/parser/keyword-as-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
+
+fn main() {
+ let as = "foo"; //~ error: expected identifier, found keyword `as`
+}
diff --git a/src/test/ui/parser/keyword-as-as-identifier.stderr b/src/test/ui/parser/keyword-as-as-identifier.stderr
new file mode 100644
index 000000000..3c5ad950d
--- /dev/null
+++ b/src/test/ui/parser/keyword-as-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `as`
+ --> $DIR/keyword-as-as-identifier.rs:4:9
+ |
+LL | let as = "foo";
+ | ^^ expected identifier, found keyword
+ |
+help: escape `as` to use it as an identifier
+ |
+LL | let r#as = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-box-as-identifier.rs b/src/test/ui/parser/keyword-box-as-identifier.rs
new file mode 100644
index 000000000..2cf49b66b
--- /dev/null
+++ b/src/test/ui/parser/keyword-box-as-identifier.rs
@@ -0,0 +1,10 @@
+fn main() {
+ let box = 0;
+ //~^ ERROR expected pattern, found `=`
+ let box: bool;
+ //~^ ERROR expected pattern, found `:`
+ let mut box = 0;
+ //~^ ERROR expected pattern, found `=`
+ let (box,) = (0,);
+ //~^ ERROR expected pattern, found `,`
+}
diff --git a/src/test/ui/parser/keyword-box-as-identifier.stderr b/src/test/ui/parser/keyword-box-as-identifier.stderr
new file mode 100644
index 000000000..eaa1f8003
--- /dev/null
+++ b/src/test/ui/parser/keyword-box-as-identifier.stderr
@@ -0,0 +1,66 @@
+error: expected pattern, found `=`
+ --> $DIR/keyword-box-as-identifier.rs:2:13
+ |
+LL | let box = 0;
+ | ^
+ |
+note: `box` is a reserved keyword
+ --> $DIR/keyword-box-as-identifier.rs:2:9
+ |
+LL | let box = 0;
+ | ^^^
+help: escape `box` to use it as an identifier
+ |
+LL | let r#box = 0;
+ | ++
+
+error: expected pattern, found `:`
+ --> $DIR/keyword-box-as-identifier.rs:4:12
+ |
+LL | let box: bool;
+ | ^
+ |
+note: `box` is a reserved keyword
+ --> $DIR/keyword-box-as-identifier.rs:4:9
+ |
+LL | let box: bool;
+ | ^^^
+help: escape `box` to use it as an identifier
+ |
+LL | let r#box: bool;
+ | ++
+
+error: expected pattern, found `=`
+ --> $DIR/keyword-box-as-identifier.rs:6:17
+ |
+LL | let mut box = 0;
+ | ^
+ |
+note: `box` is a reserved keyword
+ --> $DIR/keyword-box-as-identifier.rs:6:13
+ |
+LL | let mut box = 0;
+ | ^^^
+help: escape `box` to use it as an identifier
+ |
+LL | let mut r#box = 0;
+ | ++
+
+error: expected pattern, found `,`
+ --> $DIR/keyword-box-as-identifier.rs:8:13
+ |
+LL | let (box,) = (0,);
+ | ^
+ |
+note: `box` is a reserved keyword
+ --> $DIR/keyword-box-as-identifier.rs:8:10
+ |
+LL | let (box,) = (0,);
+ | ^^^
+help: escape `box` to use it as an identifier
+ |
+LL | let (r#box,) = (0,);
+ | ++
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/keyword-break-as-identifier.rs b/src/test/ui/parser/keyword-break-as-identifier.rs
new file mode 100644
index 000000000..04b25a7aa
--- /dev/null
+++ b/src/test/ui/parser/keyword-break-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
+
+fn main() {
+ let break = "foo"; //~ error: expected identifier, found keyword `break`
+}
diff --git a/src/test/ui/parser/keyword-break-as-identifier.stderr b/src/test/ui/parser/keyword-break-as-identifier.stderr
new file mode 100644
index 000000000..a4535eb40
--- /dev/null
+++ b/src/test/ui/parser/keyword-break-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `break`
+ --> $DIR/keyword-break-as-identifier.rs:4:9
+ |
+LL | let break = "foo";
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `break` to use it as an identifier
+ |
+LL | let r#break = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-const-as-identifier.rs b/src/test/ui/parser/keyword-const-as-identifier.rs
new file mode 100644
index 000000000..6a2d926bf
--- /dev/null
+++ b/src/test/ui/parser/keyword-const-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py const'
+
+fn main() {
+ let const = "foo"; //~ error: expected identifier, found keyword `const`
+}
diff --git a/src/test/ui/parser/keyword-const-as-identifier.stderr b/src/test/ui/parser/keyword-const-as-identifier.stderr
new file mode 100644
index 000000000..31922f150
--- /dev/null
+++ b/src/test/ui/parser/keyword-const-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `const`
+ --> $DIR/keyword-const-as-identifier.rs:4:9
+ |
+LL | let const = "foo";
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `const` to use it as an identifier
+ |
+LL | let r#const = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-continue-as-identifier.rs b/src/test/ui/parser/keyword-continue-as-identifier.rs
new file mode 100644
index 000000000..cfdd62a2d
--- /dev/null
+++ b/src/test/ui/parser/keyword-continue-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py continue'
+
+fn main() {
+ let continue = "foo"; //~ error: expected identifier, found keyword `continue`
+}
diff --git a/src/test/ui/parser/keyword-continue-as-identifier.stderr b/src/test/ui/parser/keyword-continue-as-identifier.stderr
new file mode 100644
index 000000000..81285633f
--- /dev/null
+++ b/src/test/ui/parser/keyword-continue-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `continue`
+ --> $DIR/keyword-continue-as-identifier.rs:4:9
+ |
+LL | let continue = "foo";
+ | ^^^^^^^^ expected identifier, found keyword
+ |
+help: escape `continue` to use it as an identifier
+ |
+LL | let r#continue = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-else-as-identifier.rs b/src/test/ui/parser/keyword-else-as-identifier.rs
new file mode 100644
index 000000000..f12dac3ff
--- /dev/null
+++ b/src/test/ui/parser/keyword-else-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
+
+fn main() {
+ let else = "foo"; //~ error: expected identifier, found keyword `else`
+}
diff --git a/src/test/ui/parser/keyword-else-as-identifier.stderr b/src/test/ui/parser/keyword-else-as-identifier.stderr
new file mode 100644
index 000000000..2125fe84a
--- /dev/null
+++ b/src/test/ui/parser/keyword-else-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `else`
+ --> $DIR/keyword-else-as-identifier.rs:4:9
+ |
+LL | let else = "foo";
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `else` to use it as an identifier
+ |
+LL | let r#else = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-enum-as-identifier.rs b/src/test/ui/parser/keyword-enum-as-identifier.rs
new file mode 100644
index 000000000..fe66230d0
--- /dev/null
+++ b/src/test/ui/parser/keyword-enum-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
+
+fn main() {
+ let enum = "foo"; //~ error: expected identifier, found keyword `enum`
+}
diff --git a/src/test/ui/parser/keyword-enum-as-identifier.stderr b/src/test/ui/parser/keyword-enum-as-identifier.stderr
new file mode 100644
index 000000000..92d092ccb
--- /dev/null
+++ b/src/test/ui/parser/keyword-enum-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `enum`
+ --> $DIR/keyword-enum-as-identifier.rs:4:9
+ |
+LL | let enum = "foo";
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `enum` to use it as an identifier
+ |
+LL | let r#enum = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-final.rs b/src/test/ui/parser/keyword-final.rs
new file mode 100644
index 000000000..a79a11032
--- /dev/null
+++ b/src/test/ui/parser/keyword-final.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let final = (); //~ ERROR expected identifier, found reserved keyword `final`
+}
diff --git a/src/test/ui/parser/keyword-final.stderr b/src/test/ui/parser/keyword-final.stderr
new file mode 100644
index 000000000..f1f9f2e2c
--- /dev/null
+++ b/src/test/ui/parser/keyword-final.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found reserved keyword `final`
+ --> $DIR/keyword-final.rs:2:9
+ |
+LL | let final = ();
+ | ^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `final` to use it as an identifier
+ |
+LL | let r#final = ();
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-fn-as-identifier.rs b/src/test/ui/parser/keyword-fn-as-identifier.rs
new file mode 100644
index 000000000..f30e115f7
--- /dev/null
+++ b/src/test/ui/parser/keyword-fn-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
+
+fn main() {
+ let fn = "foo"; //~ error: expected identifier, found keyword `fn`
+}
diff --git a/src/test/ui/parser/keyword-fn-as-identifier.stderr b/src/test/ui/parser/keyword-fn-as-identifier.stderr
new file mode 100644
index 000000000..645efbcae
--- /dev/null
+++ b/src/test/ui/parser/keyword-fn-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `fn`
+ --> $DIR/keyword-fn-as-identifier.rs:4:9
+ |
+LL | let fn = "foo";
+ | ^^ expected identifier, found keyword
+ |
+help: escape `fn` to use it as an identifier
+ |
+LL | let r#fn = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-for-as-identifier.rs b/src/test/ui/parser/keyword-for-as-identifier.rs
new file mode 100644
index 000000000..9e8a2ad53
--- /dev/null
+++ b/src/test/ui/parser/keyword-for-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
+
+fn main() {
+ let for = "foo"; //~ error: expected identifier, found keyword `for`
+}
diff --git a/src/test/ui/parser/keyword-for-as-identifier.stderr b/src/test/ui/parser/keyword-for-as-identifier.stderr
new file mode 100644
index 000000000..26407cc4d
--- /dev/null
+++ b/src/test/ui/parser/keyword-for-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `for`
+ --> $DIR/keyword-for-as-identifier.rs:4:9
+ |
+LL | let for = "foo";
+ | ^^^ expected identifier, found keyword
+ |
+help: escape `for` to use it as an identifier
+ |
+LL | let r#for = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-if-as-identifier.rs b/src/test/ui/parser/keyword-if-as-identifier.rs
new file mode 100644
index 000000000..0bd5756af
--- /dev/null
+++ b/src/test/ui/parser/keyword-if-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
+
+fn main() {
+ let if = "foo"; //~ error: expected identifier, found keyword `if`
+}
diff --git a/src/test/ui/parser/keyword-if-as-identifier.stderr b/src/test/ui/parser/keyword-if-as-identifier.stderr
new file mode 100644
index 000000000..26f9a15a7
--- /dev/null
+++ b/src/test/ui/parser/keyword-if-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `if`
+ --> $DIR/keyword-if-as-identifier.rs:4:9
+ |
+LL | let if = "foo";
+ | ^^ expected identifier, found keyword
+ |
+help: escape `if` to use it as an identifier
+ |
+LL | let r#if = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-impl-as-identifier.rs b/src/test/ui/parser/keyword-impl-as-identifier.rs
new file mode 100644
index 000000000..df529bae0
--- /dev/null
+++ b/src/test/ui/parser/keyword-impl-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
+
+fn main() {
+ let impl = "foo"; //~ error: expected identifier, found keyword `impl`
+}
diff --git a/src/test/ui/parser/keyword-impl-as-identifier.stderr b/src/test/ui/parser/keyword-impl-as-identifier.stderr
new file mode 100644
index 000000000..73a50bc38
--- /dev/null
+++ b/src/test/ui/parser/keyword-impl-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `impl`
+ --> $DIR/keyword-impl-as-identifier.rs:4:9
+ |
+LL | let impl = "foo";
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `impl` to use it as an identifier
+ |
+LL | let r#impl = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-in-as-identifier.rs b/src/test/ui/parser/keyword-in-as-identifier.rs
new file mode 100644
index 000000000..e4499dea2
--- /dev/null
+++ b/src/test/ui/parser/keyword-in-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py in'
+
+fn main() {
+ let in = "foo"; //~ error: expected pattern, found keyword `in`
+}
diff --git a/src/test/ui/parser/keyword-in-as-identifier.stderr b/src/test/ui/parser/keyword-in-as-identifier.stderr
new file mode 100644
index 000000000..98332b723
--- /dev/null
+++ b/src/test/ui/parser/keyword-in-as-identifier.stderr
@@ -0,0 +1,8 @@
+error: expected pattern, found keyword `in`
+ --> $DIR/keyword-in-as-identifier.rs:4:9
+ |
+LL | let in = "foo";
+ | ^^ expected pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-let-as-identifier.rs b/src/test/ui/parser/keyword-let-as-identifier.rs
new file mode 100644
index 000000000..9b1183501
--- /dev/null
+++ b/src/test/ui/parser/keyword-let-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
+
+fn main() {
+ let let = "foo"; //~ error: expected identifier, found keyword `let`
+}
diff --git a/src/test/ui/parser/keyword-let-as-identifier.stderr b/src/test/ui/parser/keyword-let-as-identifier.stderr
new file mode 100644
index 000000000..86faaed38
--- /dev/null
+++ b/src/test/ui/parser/keyword-let-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `let`
+ --> $DIR/keyword-let-as-identifier.rs:4:9
+ |
+LL | let let = "foo";
+ | ^^^ expected identifier, found keyword
+ |
+help: escape `let` to use it as an identifier
+ |
+LL | let r#let = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-loop-as-identifier.rs b/src/test/ui/parser/keyword-loop-as-identifier.rs
new file mode 100644
index 000000000..46914a19b
--- /dev/null
+++ b/src/test/ui/parser/keyword-loop-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
+
+fn main() {
+ let loop = "foo"; //~ error: expected identifier, found keyword `loop`
+}
diff --git a/src/test/ui/parser/keyword-loop-as-identifier.stderr b/src/test/ui/parser/keyword-loop-as-identifier.stderr
new file mode 100644
index 000000000..304ad61cc
--- /dev/null
+++ b/src/test/ui/parser/keyword-loop-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `loop`
+ --> $DIR/keyword-loop-as-identifier.rs:4:9
+ |
+LL | let loop = "foo";
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `loop` to use it as an identifier
+ |
+LL | let r#loop = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-match-as-identifier.rs b/src/test/ui/parser/keyword-match-as-identifier.rs
new file mode 100644
index 000000000..d3cecb991
--- /dev/null
+++ b/src/test/ui/parser/keyword-match-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
+
+fn main() {
+ let match = "foo"; //~ error: expected identifier, found keyword `match`
+}
diff --git a/src/test/ui/parser/keyword-match-as-identifier.stderr b/src/test/ui/parser/keyword-match-as-identifier.stderr
new file mode 100644
index 000000000..25ac397fb
--- /dev/null
+++ b/src/test/ui/parser/keyword-match-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `match`
+ --> $DIR/keyword-match-as-identifier.rs:4:9
+ |
+LL | let match = "foo";
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `match` to use it as an identifier
+ |
+LL | let r#match = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-mod-as-identifier.rs b/src/test/ui/parser/keyword-mod-as-identifier.rs
new file mode 100644
index 000000000..b9c7b6c78
--- /dev/null
+++ b/src/test/ui/parser/keyword-mod-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
+
+fn main() {
+ let mod = "foo"; //~ error: expected identifier, found keyword `mod`
+}
diff --git a/src/test/ui/parser/keyword-mod-as-identifier.stderr b/src/test/ui/parser/keyword-mod-as-identifier.stderr
new file mode 100644
index 000000000..d5688e871
--- /dev/null
+++ b/src/test/ui/parser/keyword-mod-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `mod`
+ --> $DIR/keyword-mod-as-identifier.rs:4:9
+ |
+LL | let mod = "foo";
+ | ^^^ expected identifier, found keyword
+ |
+help: escape `mod` to use it as an identifier
+ |
+LL | let r#mod = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-move-as-identifier.rs b/src/test/ui/parser/keyword-move-as-identifier.rs
new file mode 100644
index 000000000..65be02e3c
--- /dev/null
+++ b/src/test/ui/parser/keyword-move-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py move'
+
+fn main() {
+ let move = "foo"; //~ error: expected identifier, found keyword `move`
+}
diff --git a/src/test/ui/parser/keyword-move-as-identifier.stderr b/src/test/ui/parser/keyword-move-as-identifier.stderr
new file mode 100644
index 000000000..75653cffc
--- /dev/null
+++ b/src/test/ui/parser/keyword-move-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `move`
+ --> $DIR/keyword-move-as-identifier.rs:4:9
+ |
+LL | let move = "foo";
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `move` to use it as an identifier
+ |
+LL | let r#move = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-mut-as-identifier.rs b/src/test/ui/parser/keyword-mut-as-identifier.rs
new file mode 100644
index 000000000..9b919d2b3
--- /dev/null
+++ b/src/test/ui/parser/keyword-mut-as-identifier.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let mut = "foo"; //~ error: expected identifier, found `=`
+}
diff --git a/src/test/ui/parser/keyword-mut-as-identifier.stderr b/src/test/ui/parser/keyword-mut-as-identifier.stderr
new file mode 100644
index 000000000..040960835
--- /dev/null
+++ b/src/test/ui/parser/keyword-mut-as-identifier.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `=`
+ --> $DIR/keyword-mut-as-identifier.rs:2:13
+ |
+LL | let mut = "foo";
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-override.rs b/src/test/ui/parser/keyword-override.rs
new file mode 100644
index 000000000..009bebd7d
--- /dev/null
+++ b/src/test/ui/parser/keyword-override.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let override = (); //~ ERROR expected identifier, found reserved keyword `override`
+}
diff --git a/src/test/ui/parser/keyword-override.stderr b/src/test/ui/parser/keyword-override.stderr
new file mode 100644
index 000000000..cdb573686
--- /dev/null
+++ b/src/test/ui/parser/keyword-override.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found reserved keyword `override`
+ --> $DIR/keyword-override.rs:2:9
+ |
+LL | let override = ();
+ | ^^^^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `override` to use it as an identifier
+ |
+LL | let r#override = ();
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-pub-as-identifier.rs b/src/test/ui/parser/keyword-pub-as-identifier.rs
new file mode 100644
index 000000000..2b2bb1411
--- /dev/null
+++ b/src/test/ui/parser/keyword-pub-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
+
+fn main() {
+ let pub = "foo"; //~ error: expected identifier, found keyword `pub`
+}
diff --git a/src/test/ui/parser/keyword-pub-as-identifier.stderr b/src/test/ui/parser/keyword-pub-as-identifier.stderr
new file mode 100644
index 000000000..8d513507c
--- /dev/null
+++ b/src/test/ui/parser/keyword-pub-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `pub`
+ --> $DIR/keyword-pub-as-identifier.rs:4:9
+ |
+LL | let pub = "foo";
+ | ^^^ expected identifier, found keyword
+ |
+help: escape `pub` to use it as an identifier
+ |
+LL | let r#pub = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-ref-as-identifier.rs b/src/test/ui/parser/keyword-ref-as-identifier.rs
new file mode 100644
index 000000000..f5e04b5db
--- /dev/null
+++ b/src/test/ui/parser/keyword-ref-as-identifier.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let ref = "foo"; //~ error: expected identifier, found `=`
+}
diff --git a/src/test/ui/parser/keyword-ref-as-identifier.stderr b/src/test/ui/parser/keyword-ref-as-identifier.stderr
new file mode 100644
index 000000000..618043d89
--- /dev/null
+++ b/src/test/ui/parser/keyword-ref-as-identifier.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `=`
+ --> $DIR/keyword-ref-as-identifier.rs:2:13
+ |
+LL | let ref = "foo";
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-return-as-identifier.rs b/src/test/ui/parser/keyword-return-as-identifier.rs
new file mode 100644
index 000000000..e1a2db5e4
--- /dev/null
+++ b/src/test/ui/parser/keyword-return-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
+
+fn main() {
+ let return = "foo"; //~ error: expected identifier, found keyword `return`
+}
diff --git a/src/test/ui/parser/keyword-return-as-identifier.stderr b/src/test/ui/parser/keyword-return-as-identifier.stderr
new file mode 100644
index 000000000..eeb8e468b
--- /dev/null
+++ b/src/test/ui/parser/keyword-return-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `return`
+ --> $DIR/keyword-return-as-identifier.rs:4:9
+ |
+LL | let return = "foo";
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `return` to use it as an identifier
+ |
+LL | let r#return = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-static-as-identifier.rs b/src/test/ui/parser/keyword-static-as-identifier.rs
new file mode 100644
index 000000000..423b9854b
--- /dev/null
+++ b/src/test/ui/parser/keyword-static-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
+
+fn main() {
+ let static = "foo"; //~ error: expected identifier, found keyword `static`
+}
diff --git a/src/test/ui/parser/keyword-static-as-identifier.stderr b/src/test/ui/parser/keyword-static-as-identifier.stderr
new file mode 100644
index 000000000..a3213e2f2
--- /dev/null
+++ b/src/test/ui/parser/keyword-static-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `static`
+ --> $DIR/keyword-static-as-identifier.rs:4:9
+ |
+LL | let static = "foo";
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `static` to use it as an identifier
+ |
+LL | let r#static = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-struct-as-identifier.rs b/src/test/ui/parser/keyword-struct-as-identifier.rs
new file mode 100644
index 000000000..18cfe1159
--- /dev/null
+++ b/src/test/ui/parser/keyword-struct-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
+
+fn main() {
+ let struct = "foo"; //~ error: expected identifier, found keyword `struct`
+}
diff --git a/src/test/ui/parser/keyword-struct-as-identifier.stderr b/src/test/ui/parser/keyword-struct-as-identifier.stderr
new file mode 100644
index 000000000..b73361a55
--- /dev/null
+++ b/src/test/ui/parser/keyword-struct-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `struct`
+ --> $DIR/keyword-struct-as-identifier.rs:4:9
+ |
+LL | let struct = "foo";
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `struct` to use it as an identifier
+ |
+LL | let r#struct = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-trait-as-identifier.rs b/src/test/ui/parser/keyword-trait-as-identifier.rs
new file mode 100644
index 000000000..67f81167d
--- /dev/null
+++ b/src/test/ui/parser/keyword-trait-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
+
+fn main() {
+ let trait = "foo"; //~ error: expected identifier, found keyword `trait`
+}
diff --git a/src/test/ui/parser/keyword-trait-as-identifier.stderr b/src/test/ui/parser/keyword-trait-as-identifier.stderr
new file mode 100644
index 000000000..56ef5f606
--- /dev/null
+++ b/src/test/ui/parser/keyword-trait-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `trait`
+ --> $DIR/keyword-trait-as-identifier.rs:4:9
+ |
+LL | let trait = "foo";
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `trait` to use it as an identifier
+ |
+LL | let r#trait = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs b/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs
new file mode 100644
index 000000000..4fa37bdb0
--- /dev/null
+++ b/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs
@@ -0,0 +1,5 @@
+// compile-flags: --edition 2018
+
+fn main() {
+ let try = "foo"; //~ error: expected identifier, found reserved keyword `try`
+}
diff --git a/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr b/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr
new file mode 100644
index 000000000..94a106d47
--- /dev/null
+++ b/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found reserved keyword `try`
+ --> $DIR/keyword-try-as-identifier-edition2018.rs:4:9
+ |
+LL | let try = "foo";
+ | ^^^ expected identifier, found reserved keyword
+ |
+help: escape `try` to use it as an identifier
+ |
+LL | let r#try = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-type-as-identifier.rs b/src/test/ui/parser/keyword-type-as-identifier.rs
new file mode 100644
index 000000000..04adddf72
--- /dev/null
+++ b/src/test/ui/parser/keyword-type-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
+
+fn main() {
+ let type = "foo"; //~ error: expected identifier, found keyword `type`
+}
diff --git a/src/test/ui/parser/keyword-type-as-identifier.stderr b/src/test/ui/parser/keyword-type-as-identifier.stderr
new file mode 100644
index 000000000..624c1006b
--- /dev/null
+++ b/src/test/ui/parser/keyword-type-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `type`
+ --> $DIR/keyword-type-as-identifier.rs:4:9
+ |
+LL | let type = "foo";
+ | ^^^^ expected identifier, found keyword
+ |
+help: escape `type` to use it as an identifier
+ |
+LL | let r#type = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-typeof.rs b/src/test/ui/parser/keyword-typeof.rs
new file mode 100644
index 000000000..29dc77d27
--- /dev/null
+++ b/src/test/ui/parser/keyword-typeof.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let typeof = (); //~ ERROR expected identifier, found reserved keyword `typeof`
+}
diff --git a/src/test/ui/parser/keyword-typeof.stderr b/src/test/ui/parser/keyword-typeof.stderr
new file mode 100644
index 000000000..4c5324505
--- /dev/null
+++ b/src/test/ui/parser/keyword-typeof.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found reserved keyword `typeof`
+ --> $DIR/keyword-typeof.rs:2:9
+ |
+LL | let typeof = ();
+ | ^^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `typeof` to use it as an identifier
+ |
+LL | let r#typeof = ();
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-unsafe-as-identifier.rs b/src/test/ui/parser/keyword-unsafe-as-identifier.rs
new file mode 100644
index 000000000..0ff6d188c
--- /dev/null
+++ b/src/test/ui/parser/keyword-unsafe-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
+
+fn main() {
+ let unsafe = "foo"; //~ error: expected identifier, found keyword `unsafe`
+}
diff --git a/src/test/ui/parser/keyword-unsafe-as-identifier.stderr b/src/test/ui/parser/keyword-unsafe-as-identifier.stderr
new file mode 100644
index 000000000..b552c9cd3
--- /dev/null
+++ b/src/test/ui/parser/keyword-unsafe-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `unsafe`
+ --> $DIR/keyword-unsafe-as-identifier.rs:4:9
+ |
+LL | let unsafe = "foo";
+ | ^^^^^^ expected identifier, found keyword
+ |
+help: escape `unsafe` to use it as an identifier
+ |
+LL | let r#unsafe = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-use-as-identifier.rs b/src/test/ui/parser/keyword-use-as-identifier.rs
new file mode 100644
index 000000000..821bedee0
--- /dev/null
+++ b/src/test/ui/parser/keyword-use-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
+
+fn main() {
+ let use = "foo"; //~ error: expected identifier, found keyword `use`
+}
diff --git a/src/test/ui/parser/keyword-use-as-identifier.stderr b/src/test/ui/parser/keyword-use-as-identifier.stderr
new file mode 100644
index 000000000..630798659
--- /dev/null
+++ b/src/test/ui/parser/keyword-use-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `use`
+ --> $DIR/keyword-use-as-identifier.rs:4:9
+ |
+LL | let use = "foo";
+ | ^^^ expected identifier, found keyword
+ |
+help: escape `use` to use it as an identifier
+ |
+LL | let r#use = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-where-as-identifier.rs b/src/test/ui/parser/keyword-where-as-identifier.rs
new file mode 100644
index 000000000..56301bd20
--- /dev/null
+++ b/src/test/ui/parser/keyword-where-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py where'
+
+fn main() {
+ let where = "foo"; //~ error: expected identifier, found keyword `where`
+}
diff --git a/src/test/ui/parser/keyword-where-as-identifier.stderr b/src/test/ui/parser/keyword-where-as-identifier.stderr
new file mode 100644
index 000000000..9e72f7940
--- /dev/null
+++ b/src/test/ui/parser/keyword-where-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `where`
+ --> $DIR/keyword-where-as-identifier.rs:4:9
+ |
+LL | let where = "foo";
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `where` to use it as an identifier
+ |
+LL | let r#where = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword-while-as-identifier.rs b/src/test/ui/parser/keyword-while-as-identifier.rs
new file mode 100644
index 000000000..22026d15d
--- /dev/null
+++ b/src/test/ui/parser/keyword-while-as-identifier.rs
@@ -0,0 +1,5 @@
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
+
+fn main() {
+ let while = "foo"; //~ error: expected identifier, found keyword `while`
+}
diff --git a/src/test/ui/parser/keyword-while-as-identifier.stderr b/src/test/ui/parser/keyword-while-as-identifier.stderr
new file mode 100644
index 000000000..2bb62105d
--- /dev/null
+++ b/src/test/ui/parser/keyword-while-as-identifier.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `while`
+ --> $DIR/keyword-while-as-identifier.rs:4:9
+ |
+LL | let while = "foo";
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `while` to use it as an identifier
+ |
+LL | let r#while = "foo";
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keyword.rs b/src/test/ui/parser/keyword.rs
new file mode 100644
index 000000000..1eb7886c5
--- /dev/null
+++ b/src/test/ui/parser/keyword.rs
@@ -0,0 +1,5 @@
+pub mod break {
+ //~^ ERROR expected identifier, found keyword `break`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/keyword.stderr b/src/test/ui/parser/keyword.stderr
new file mode 100644
index 000000000..ee7d72b39
--- /dev/null
+++ b/src/test/ui/parser/keyword.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found keyword `break`
+ --> $DIR/keyword.rs:1:9
+ |
+LL | pub mod break {
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `break` to use it as an identifier
+ |
+LL | pub mod r#break {
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/keywords-followed-by-double-colon.rs b/src/test/ui/parser/keywords-followed-by-double-colon.rs
new file mode 100644
index 000000000..5c7049f7c
--- /dev/null
+++ b/src/test/ui/parser/keywords-followed-by-double-colon.rs
@@ -0,0 +1,8 @@
+fn main() {
+ struct::foo();
+ //~^ ERROR expected identifier
+}
+fn bar() {
+ mut::baz();
+ //~^ ERROR expected expression, found keyword `mut`
+}
diff --git a/src/test/ui/parser/keywords-followed-by-double-colon.stderr b/src/test/ui/parser/keywords-followed-by-double-colon.stderr
new file mode 100644
index 000000000..4c4d5e5dd
--- /dev/null
+++ b/src/test/ui/parser/keywords-followed-by-double-colon.stderr
@@ -0,0 +1,14 @@
+error: expected identifier, found `::`
+ --> $DIR/keywords-followed-by-double-colon.rs:2:11
+ |
+LL | struct::foo();
+ | ^^ expected identifier
+
+error: expected expression, found keyword `mut`
+ --> $DIR/keywords-followed-by-double-colon.rs:6:5
+ |
+LL | mut::baz();
+ | ^^^ expected expression
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/labeled-no-colon-expr.rs b/src/test/ui/parser/labeled-no-colon-expr.rs
new file mode 100644
index 000000000..db9ef52c1
--- /dev/null
+++ b/src/test/ui/parser/labeled-no-colon-expr.rs
@@ -0,0 +1,17 @@
+#![feature(label_break_value)]
+
+fn main() {
+ 'l0 while false {} //~ ERROR labeled expression must be followed by `:`
+ 'l1 for _ in 0..1 {} //~ ERROR labeled expression must be followed by `:`
+ 'l2 loop {} //~ ERROR labeled expression must be followed by `:`
+ 'l3 {} //~ ERROR labeled expression must be followed by `:`
+ 'l4 0; //~ ERROR labeled expression must be followed by `:`
+ //~^ ERROR expected `while`, `for`, `loop` or `{`
+
+ macro_rules! m {
+ ($b:block) => {
+ 'l5 $b; //~ ERROR cannot use a `block` macro fragment here
+ }
+ }
+ m!({}); //~ ERROR labeled expression must be followed by `:`
+}
diff --git a/src/test/ui/parser/labeled-no-colon-expr.stderr b/src/test/ui/parser/labeled-no-colon-expr.stderr
new file mode 100644
index 000000000..a258bd3cc
--- /dev/null
+++ b/src/test/ui/parser/labeled-no-colon-expr.stderr
@@ -0,0 +1,95 @@
+error: labeled expression must be followed by `:`
+ --> $DIR/labeled-no-colon-expr.rs:4:5
+ |
+LL | 'l0 while false {}
+ | ----^^^^^^^^^^^^^^
+ | | |
+ | | help: add `:` after the label
+ | the label
+ |
+ = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
+
+error: labeled expression must be followed by `:`
+ --> $DIR/labeled-no-colon-expr.rs:5:5
+ |
+LL | 'l1 for _ in 0..1 {}
+ | ----^^^^^^^^^^^^^^^^
+ | | |
+ | | help: add `:` after the label
+ | the label
+ |
+ = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
+
+error: labeled expression must be followed by `:`
+ --> $DIR/labeled-no-colon-expr.rs:6:5
+ |
+LL | 'l2 loop {}
+ | ----^^^^^^^
+ | | |
+ | | help: add `:` after the label
+ | the label
+ |
+ = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
+
+error: labeled expression must be followed by `:`
+ --> $DIR/labeled-no-colon-expr.rs:7:5
+ |
+LL | 'l3 {}
+ | ----^^
+ | | |
+ | | help: add `:` after the label
+ | the label
+ |
+ = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/labeled-no-colon-expr.rs:8:9
+ |
+LL | 'l4 0;
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider removing the label
+ |
+LL - 'l4 0;
+LL + 0;
+ |
+
+error: labeled expression must be followed by `:`
+ --> $DIR/labeled-no-colon-expr.rs:8:9
+ |
+LL | 'l4 0;
+ | ----^
+ | | |
+ | | help: add `:` after the label
+ | the label
+ |
+ = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
+
+error: cannot use a `block` macro fragment here
+ --> $DIR/labeled-no-colon-expr.rs:13:17
+ |
+LL | 'l5 $b;
+ | ----^^
+ | |
+ | the `block` fragment is within this context
+...
+LL | m!({});
+ | ------ in this macro invocation
+ |
+ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: labeled expression must be followed by `:`
+ --> $DIR/labeled-no-colon-expr.rs:16:8
+ |
+LL | 'l5 $b;
+ | ---- help: add `:` after the label
+ | |
+ | the label
+...
+LL | m!({});
+ | ^^
+ |
+ = note: labels are used before loops and blocks, allowing e.g., `break 'label` to them
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/parser/let-binop.fixed b/src/test/ui/parser/let-binop.fixed
new file mode 100644
index 000000000..93f7f97b0
--- /dev/null
+++ b/src/test/ui/parser/let-binop.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+ let a: i8 = 1; //~ ERROR can't reassign to an uninitialized variable
+ let _ = a;
+ let b = 1; //~ ERROR can't reassign to an uninitialized variable
+ let _ = b;
+ let c = 1; //~ ERROR can't reassign to an uninitialized variable
+ let _ = c;
+}
diff --git a/src/test/ui/parser/let-binop.rs b/src/test/ui/parser/let-binop.rs
new file mode 100644
index 000000000..2adbceae5
--- /dev/null
+++ b/src/test/ui/parser/let-binop.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+ let a: i8 *= 1; //~ ERROR can't reassign to an uninitialized variable
+ let _ = a;
+ let b += 1; //~ ERROR can't reassign to an uninitialized variable
+ let _ = b;
+ let c *= 1; //~ ERROR can't reassign to an uninitialized variable
+ let _ = c;
+}
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
new file mode 100644
index 000000000..dd33e9157
--- /dev/null
+++ b/src/test/ui/parser/let-binop.stderr
@@ -0,0 +1,26 @@
+error: can't reassign to an uninitialized variable
+ --> $DIR/let-binop.rs:4:15
+ |
+LL | let a: i8 *= 1;
+ | ^^ help: initialize the variable
+ |
+ = help: if you meant to overwrite, remove the `let` binding
+
+error: can't reassign to an uninitialized variable
+ --> $DIR/let-binop.rs:6:11
+ |
+LL | let b += 1;
+ | ^^ help: initialize the variable
+ |
+ = help: if you meant to overwrite, remove the `let` binding
+
+error: can't reassign to an uninitialized variable
+ --> $DIR/let-binop.rs:8:11
+ |
+LL | let c *= 1;
+ | ^^ help: initialize the variable
+ |
+ = help: if you meant to overwrite, remove the `let` binding
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/lifetime-in-pattern-recover.rs b/src/test/ui/parser/lifetime-in-pattern-recover.rs
new file mode 100644
index 000000000..7fb14b800
--- /dev/null
+++ b/src/test/ui/parser/lifetime-in-pattern-recover.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let &'a x = &0; //~ ERROR unexpected lifetime `'a` in pattern
+ let &'a mut y = &mut 0; //~ ERROR unexpected lifetime `'a` in pattern
+
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/lifetime-in-pattern-recover.stderr b/src/test/ui/parser/lifetime-in-pattern-recover.stderr
new file mode 100644
index 000000000..4bf7f57bf
--- /dev/null
+++ b/src/test/ui/parser/lifetime-in-pattern-recover.stderr
@@ -0,0 +1,23 @@
+error: unexpected lifetime `'a` in pattern
+ --> $DIR/lifetime-in-pattern-recover.rs:2:10
+ |
+LL | let &'a x = &0;
+ | ^^ help: remove the lifetime
+
+error: unexpected lifetime `'a` in pattern
+ --> $DIR/lifetime-in-pattern-recover.rs:3:10
+ |
+LL | let &'a mut y = &mut 0;
+ | ^^ help: remove the lifetime
+
+error[E0308]: mismatched types
+ --> $DIR/lifetime-in-pattern-recover.rs:5:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/lifetime-in-pattern.rs b/src/test/ui/parser/lifetime-in-pattern.rs
new file mode 100644
index 000000000..d3c638d0c
--- /dev/null
+++ b/src/test/ui/parser/lifetime-in-pattern.rs
@@ -0,0 +1,7 @@
+fn test(&'a str) {
+ //~^ ERROR unexpected lifetime `'a` in pattern
+ //~| ERROR expected one of `:`, `@`, or `|`, found `)`
+}
+
+fn main() {
+}
diff --git a/src/test/ui/parser/lifetime-in-pattern.stderr b/src/test/ui/parser/lifetime-in-pattern.stderr
new file mode 100644
index 000000000..a1d721e74
--- /dev/null
+++ b/src/test/ui/parser/lifetime-in-pattern.stderr
@@ -0,0 +1,28 @@
+error: unexpected lifetime `'a` in pattern
+ --> $DIR/lifetime-in-pattern.rs:1:10
+ |
+LL | fn test(&'a str) {
+ | ^^ help: remove the lifetime
+
+error: expected one of `:`, `@`, or `|`, found `)`
+ --> $DIR/lifetime-in-pattern.rs:1:16
+ |
+LL | fn test(&'a str) {
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+ |
+LL | fn test(self: &'a str) {
+ | +++++
+help: if this is a parameter name, give it a type
+ |
+LL | fn test(str: &TypeName) {
+ | ~~~~~~~~~~~~~~
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn test(_: &'a str) {
+ | ++
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/lifetime-semicolon.fixed b/src/test/ui/parser/lifetime-semicolon.fixed
new file mode 100644
index 000000000..482b77046
--- /dev/null
+++ b/src/test/ui/parser/lifetime-semicolon.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+#![allow(unused)]
+struct Foo<'a, 'b> {
+ a: &'a &'b i32
+}
+
+fn foo<'a, 'b>(_x: &mut Foo<'a, 'b>) {}
+//~^ ERROR expected one of `,` or `>`, found `;`
+
+fn main() {}
diff --git a/src/test/ui/parser/lifetime-semicolon.rs b/src/test/ui/parser/lifetime-semicolon.rs
new file mode 100644
index 000000000..21c8b0a7f
--- /dev/null
+++ b/src/test/ui/parser/lifetime-semicolon.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+#![allow(unused)]
+struct Foo<'a, 'b> {
+ a: &'a &'b i32
+}
+
+fn foo<'a, 'b>(_x: &mut Foo<'a; 'b>) {}
+//~^ ERROR expected one of `,` or `>`, found `;`
+
+fn main() {}
diff --git a/src/test/ui/parser/lifetime-semicolon.stderr b/src/test/ui/parser/lifetime-semicolon.stderr
new file mode 100644
index 000000000..ee486c236
--- /dev/null
+++ b/src/test/ui/parser/lifetime-semicolon.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,` or `>`, found `;`
+ --> $DIR/lifetime-semicolon.rs:7:31
+ |
+LL | fn foo<'a, 'b>(_x: &mut Foo<'a; 'b>) {}
+ | ^ expected one of `,` or `>`
+ |
+help: use a comma to separate type parameters
+ |
+LL | fn foo<'a, 'b>(_x: &mut Foo<'a, 'b>) {}
+ | ~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/lifetime_starts_expressions.rs b/src/test/ui/parser/lifetime_starts_expressions.rs
new file mode 100644
index 000000000..903b4de6e
--- /dev/null
+++ b/src/test/ui/parser/lifetime_starts_expressions.rs
@@ -0,0 +1,39 @@
+#![allow(unused, dead_code)]
+
+fn foo() -> u32 {
+ return 'label: loop { break 'label 42; };
+}
+
+fn bar() -> u32 {
+ loop { break 'label: loop { break 'label 42; }; }
+ //~^ ERROR: parentheses are required around this expression to avoid confusion
+ //~| HELP: wrap the expression in parentheses
+}
+
+fn baz() -> u32 {
+ 'label: loop {
+ break 'label
+ //~^ WARNING: this labeled break expression is easy to confuse with an unlabeled break
+ loop { break 42; };
+ //~^ HELP: wrap this expression in parentheses
+ };
+
+ 'label2: loop {
+ break 'label2 'inner: loop { break 42; };
+ // no warnings or errors here
+ }
+}
+
+pub fn main() {
+ // Regression test for issue #86948, as resolved in #87026:
+ let a = 'first_loop: loop {
+ break 'first_loop 1;
+ };
+ let b = loop {
+ break 'inner_loop: loop {
+ //~^ ERROR: parentheses are required around this expression to avoid confusion
+ //~| HELP: wrap the expression in parentheses
+ break 'inner_loop 1;
+ };
+ };
+}
diff --git a/src/test/ui/parser/lifetime_starts_expressions.stderr b/src/test/ui/parser/lifetime_starts_expressions.stderr
new file mode 100644
index 000000000..82e274325
--- /dev/null
+++ b/src/test/ui/parser/lifetime_starts_expressions.stderr
@@ -0,0 +1,47 @@
+error: parentheses are required around this expression to avoid confusion with a labeled break expression
+ --> $DIR/lifetime_starts_expressions.rs:8:18
+ |
+LL | loop { break 'label: loop { break 'label 42; }; }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: wrap the expression in parentheses
+ |
+LL | loop { break ('label: loop { break 'label 42; }); }
+ | + +
+
+error: parentheses are required around this expression to avoid confusion with a labeled break expression
+ --> $DIR/lifetime_starts_expressions.rs:33:15
+ |
+LL | break 'inner_loop: loop {
+ | _______________^
+LL | |
+LL | |
+LL | | break 'inner_loop 1;
+LL | | };
+ | |_________^
+ |
+help: wrap the expression in parentheses
+ |
+LL ~ break ('inner_loop: loop {
+LL |
+LL |
+LL | break 'inner_loop 1;
+LL ~ });
+ |
+
+warning: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression
+ --> $DIR/lifetime_starts_expressions.rs:15:9
+ |
+LL | / break 'label
+LL | |
+LL | | loop { break 42; };
+ | |______________________________^
+ |
+ = note: `#[warn(break_with_label_and_loop)]` on by default
+help: wrap this expression in parentheses
+ |
+LL | (loop { break 42; });
+ | + +
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.rs b/src/test/ui/parser/macro-bad-delimiter-ident.rs
new file mode 100644
index 000000000..f461f06b4
--- /dev/null
+++ b/src/test/ui/parser/macro-bad-delimiter-ident.rs
@@ -0,0 +1,3 @@
+fn main() {
+ foo! bar < //~ ERROR expected one of `(`, `[`, or `{`, found `bar`
+}
diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.stderr b/src/test/ui/parser/macro-bad-delimiter-ident.stderr
new file mode 100644
index 000000000..f2365fed2
--- /dev/null
+++ b/src/test/ui/parser/macro-bad-delimiter-ident.stderr
@@ -0,0 +1,8 @@
+error: expected one of `(`, `[`, or `{`, found `bar`
+ --> $DIR/macro-bad-delimiter-ident.rs:2:10
+ |
+LL | foo! bar <
+ | ^^^ expected one of `(`, `[`, or `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro-braces-dot-question.rs b/src/test/ui/parser/macro-braces-dot-question.rs
new file mode 100644
index 000000000..016b434a6
--- /dev/null
+++ b/src/test/ui/parser/macro-braces-dot-question.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+use std::io::Write;
+
+fn main() -> Result<(), std::io::Error> {
+ vec! { 1, 2, 3 }.len();
+ write! { vec![], "" }?;
+ println!{""}
+ [0]; // separate statement, not indexing into the result of println.
+ Ok(())
+}
diff --git a/src/test/ui/parser/macro-keyword.rs b/src/test/ui/parser/macro-keyword.rs
new file mode 100644
index 000000000..58489fb2c
--- /dev/null
+++ b/src/test/ui/parser/macro-keyword.rs
@@ -0,0 +1,5 @@
+fn macro() { //~ ERROR expected identifier, found reserved keyword `macro`
+}
+
+pub fn main() {
+}
diff --git a/src/test/ui/parser/macro-keyword.stderr b/src/test/ui/parser/macro-keyword.stderr
new file mode 100644
index 000000000..d794671f8
--- /dev/null
+++ b/src/test/ui/parser/macro-keyword.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found reserved keyword `macro`
+ --> $DIR/macro-keyword.rs:1:4
+ |
+LL | fn macro() {
+ | ^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `macro` to use it as an identifier
+ |
+LL | fn r#macro() {
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro-mismatched-delim-brace-paren.rs b/src/test/ui/parser/macro-mismatched-delim-brace-paren.rs
new file mode 100644
index 000000000..404aa7b80
--- /dev/null
+++ b/src/test/ui/parser/macro-mismatched-delim-brace-paren.rs
@@ -0,0 +1,7 @@
+macro_rules! foo { ($($tt:tt)*) => () }
+
+fn main() {
+ foo! {
+ bar, "baz", 1, 2.0
+ ) //~ ERROR mismatched closing delimiter
+}
diff --git a/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr b/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr
new file mode 100644
index 000000000..077d31800
--- /dev/null
+++ b/src/test/ui/parser/macro-mismatched-delim-brace-paren.stderr
@@ -0,0 +1,11 @@
+error: mismatched closing delimiter: `)`
+ --> $DIR/macro-mismatched-delim-brace-paren.rs:4:10
+ |
+LL | foo! {
+ | ^ unclosed delimiter
+LL | bar, "baz", 1, 2.0
+LL | )
+ | ^ mismatched closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro-mismatched-delim-paren-brace.rs b/src/test/ui/parser/macro-mismatched-delim-paren-brace.rs
new file mode 100644
index 000000000..1a1b9edfb
--- /dev/null
+++ b/src/test/ui/parser/macro-mismatched-delim-paren-brace.rs
@@ -0,0 +1,5 @@
+fn main() {
+ foo! (
+ bar, "baz", 1, 2.0
+ } //~ ERROR mismatched closing delimiter
+} //~ ERROR unexpected closing delimiter: `}`
diff --git a/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr
new file mode 100644
index 000000000..967a3e6fd
--- /dev/null
+++ b/src/test/ui/parser/macro-mismatched-delim-paren-brace.stderr
@@ -0,0 +1,22 @@
+error: unexpected closing delimiter: `}`
+ --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1
+ |
+LL | fn main() {
+ | - this opening brace...
+...
+LL | }
+ | - ...matches this closing brace
+LL | }
+ | ^ unexpected closing delimiter
+
+error: mismatched closing delimiter: `}`
+ --> $DIR/macro-mismatched-delim-paren-brace.rs:2:10
+ |
+LL | foo! (
+ | ^ unclosed delimiter
+LL | bar, "baz", 1, 2.0
+LL | }
+ | ^ mismatched closing delimiter
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/macro/bad-macro-argument.rs b/src/test/ui/parser/macro/bad-macro-argument.rs
new file mode 100644
index 000000000..4b6d23890
--- /dev/null
+++ b/src/test/ui/parser/macro/bad-macro-argument.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let message = "world";
+ println!("Hello, {}", message/); //~ ERROR expected expression
+}
diff --git a/src/test/ui/parser/macro/bad-macro-argument.stderr b/src/test/ui/parser/macro/bad-macro-argument.stderr
new file mode 100644
index 000000000..3cd8accb6
--- /dev/null
+++ b/src/test/ui/parser/macro/bad-macro-argument.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found end of macro arguments
+ --> $DIR/bad-macro-argument.rs:3:35
+ |
+LL | println!("Hello, {}", message/);
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs
new file mode 100644
index 000000000..069d181e9
--- /dev/null
+++ b/src/test/ui/parser/macro/issue-33569.rs
@@ -0,0 +1,12 @@
+macro_rules! foo {
+ { $+ } => { //~ ERROR expected identifier, found `+`
+ //~^ ERROR missing fragment specifier
+ //~| ERROR missing fragment specifier
+ //~| WARN this was previously accepted
+ $(x)(y) //~ ERROR expected one of: `*`, `+`, or `?`
+ }
+}
+
+foo!();
+
+fn main() {}
diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr
new file mode 100644
index 000000000..39d49fd03
--- /dev/null
+++ b/src/test/ui/parser/macro/issue-33569.stderr
@@ -0,0 +1,30 @@
+error: expected identifier, found `+`
+ --> $DIR/issue-33569.rs:2:8
+ |
+LL | { $+ } => {
+ | ^
+
+error: expected one of: `*`, `+`, or `?`
+ --> $DIR/issue-33569.rs:6:13
+ |
+LL | $(x)(y)
+ | ^^^
+
+error: missing fragment specifier
+ --> $DIR/issue-33569.rs:2:8
+ |
+LL | { $+ } => {
+ | ^
+
+error: missing fragment specifier
+ --> $DIR/issue-33569.rs:2:8
+ |
+LL | { $+ } => {
+ | ^
+ |
+ = note: `#[deny(missing_fragment_specifier)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/macro/issue-37113.rs b/src/test/ui/parser/macro/issue-37113.rs
new file mode 100644
index 000000000..0044aa561
--- /dev/null
+++ b/src/test/ui/parser/macro/issue-37113.rs
@@ -0,0 +1,11 @@
+macro_rules! test_macro {
+ ( $( $t:ty ),* $(),*) => {
+ enum SomeEnum {
+ $( $t, )* //~ ERROR expected identifier, found `String`
+ };
+ };
+}
+
+fn main() {
+ test_macro!(String,);
+}
diff --git a/src/test/ui/parser/macro/issue-37113.stderr b/src/test/ui/parser/macro/issue-37113.stderr
new file mode 100644
index 000000000..0912858dd
--- /dev/null
+++ b/src/test/ui/parser/macro/issue-37113.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found `String`
+ --> $DIR/issue-37113.rs:4:16
+ |
+LL | $( $t, )*
+ | ^^ expected identifier
+...
+LL | test_macro!(String,);
+ | -------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `test_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro/issue-37234.rs b/src/test/ui/parser/macro/issue-37234.rs
new file mode 100644
index 000000000..4debc7479
--- /dev/null
+++ b/src/test/ui/parser/macro/issue-37234.rs
@@ -0,0 +1,9 @@
+macro_rules! failed {
+ () => {{
+ let x = 5 ""; //~ ERROR found `""`
+ }}
+}
+
+fn main() {
+ failed!();
+}
diff --git a/src/test/ui/parser/macro/issue-37234.stderr b/src/test/ui/parser/macro/issue-37234.stderr
new file mode 100644
index 000000000..d79196204
--- /dev/null
+++ b/src/test/ui/parser/macro/issue-37234.stderr
@@ -0,0 +1,13 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `""`
+ --> $DIR/issue-37234.rs:3:19
+ |
+LL | let x = 5 "";
+ | ^^ expected one of `.`, `;`, `?`, `else`, or an operator
+...
+LL | failed!();
+ | --------- in this macro invocation
+ |
+ = note: this error originates in the macro `failed` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.rs b/src/test/ui/parser/macro/literals-are-validated-before-expansion.rs
new file mode 100644
index 000000000..c3fc754b5
--- /dev/null
+++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.rs
@@ -0,0 +1,10 @@
+macro_rules! black_hole {
+ ($($tt:tt)*) => {}
+}
+
+fn main() {
+ black_hole! { '\u{FFFFFF}' }
+ //~^ ERROR: invalid unicode character escape
+ black_hole! { "this is surrogate: \u{DAAA}" }
+ //~^ ERROR: invalid unicode character escape
+}
diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr
new file mode 100644
index 000000000..e874f6249
--- /dev/null
+++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr
@@ -0,0 +1,18 @@
+error: invalid unicode character escape
+ --> $DIR/literals-are-validated-before-expansion.rs:6:20
+ |
+LL | black_hole! { '\u{FFFFFF}' }
+ | ^^^^^^^^^^ invalid escape
+ |
+ = help: unicode escape must be at most 10FFFF
+
+error: invalid unicode character escape
+ --> $DIR/literals-are-validated-before-expansion.rs:8:39
+ |
+LL | black_hole! { "this is surrogate: \u{DAAA}" }
+ | ^^^^^^^^ invalid escape
+ |
+ = help: unicode escape must not be a surrogate
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.rs b/src/test/ui/parser/macro/macro-doc-comments-1.rs
new file mode 100644
index 000000000..8d8103bb1
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-doc-comments-1.rs
@@ -0,0 +1,9 @@
+macro_rules! outer {
+ (#[$outer:meta]) => ()
+}
+
+outer! {
+ //! Inner
+} //~^ ERROR no rules expected the token `!`
+
+fn main() { }
diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.stderr b/src/test/ui/parser/macro/macro-doc-comments-1.stderr
new file mode 100644
index 000000000..0ebf3d52b
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-doc-comments-1.stderr
@@ -0,0 +1,14 @@
+error: no rules expected the token `!`
+ --> $DIR/macro-doc-comments-1.rs:6:5
+ |
+LL | macro_rules! outer {
+ | ------------------ when calling this macro
+...
+LL | //! Inner
+ | ^^^^^^^^^
+ | |
+ | no rules expected this token in macro call
+ | inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.rs b/src/test/ui/parser/macro/macro-doc-comments-2.rs
new file mode 100644
index 000000000..8f33720ae
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-doc-comments-2.rs
@@ -0,0 +1,9 @@
+macro_rules! inner {
+ (#![$inner:meta]) => ()
+}
+
+inner! {
+ /// Outer
+} //~^ ERROR no rules expected the token `[`
+
+fn main() { }
diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.stderr b/src/test/ui/parser/macro/macro-doc-comments-2.stderr
new file mode 100644
index 000000000..346d86586
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-doc-comments-2.stderr
@@ -0,0 +1,14 @@
+error: no rules expected the token `[`
+ --> $DIR/macro-doc-comments-2.rs:6:5
+ |
+LL | macro_rules! inner {
+ | ------------------ when calling this macro
+...
+LL | /// Outer
+ | ^^^^^^^^^
+ | |
+ | no rules expected this token in macro call
+ | outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.rs b/src/test/ui/parser/macro/macro-incomplete-parse.rs
new file mode 100644
index 000000000..544e4aa7b
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-incomplete-parse.rs
@@ -0,0 +1,27 @@
+macro_rules! ignored_item {
+ () => {
+ fn foo() {}
+ fn bar() {}
+ , //~ ERROR macro expansion ignores token `,`
+ }
+}
+
+macro_rules! ignored_expr {
+ () => ( 1, //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+
+ 2 )
+}
+
+macro_rules! ignored_pat {
+ () => ( 1, 2 ) //~ ERROR macro expansion ignores token `,`
+}
+
+ignored_item!();
+
+fn main() {
+ ignored_expr!();
+ match 1 {
+ ignored_pat!() => (),
+ _ => (),
+ }
+}
diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.stderr b/src/test/ui/parser/macro/macro-incomplete-parse.stderr
new file mode 100644
index 000000000..707417b72
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-incomplete-parse.stderr
@@ -0,0 +1,35 @@
+error: macro expansion ignores token `,` and any following
+ --> $DIR/macro-incomplete-parse.rs:5:9
+ |
+LL | ,
+ | ^
+...
+LL | ignored_item!();
+ | --------------- caused by the macro expansion here
+ |
+ = note: the usage of `ignored_item!` is likely invalid in item context
+
+error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
+ --> $DIR/macro-incomplete-parse.rs:10:14
+ |
+LL | () => ( 1,
+ | ^ expected one of `.`, `;`, `?`, `}`, or an operator
+...
+LL | ignored_expr!();
+ | --------------- in this macro invocation
+ |
+ = note: this error originates in the macro `ignored_expr` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: macro expansion ignores token `,` and any following
+ --> $DIR/macro-incomplete-parse.rs:16:14
+ |
+LL | () => ( 1, 2 )
+ | ^
+...
+LL | ignored_pat!() => (),
+ | -------------- caused by the macro expansion here
+ |
+ = note: the usage of `ignored_pat!` is likely invalid in pattern context
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/macro/macro-repeat.rs b/src/test/ui/parser/macro/macro-repeat.rs
new file mode 100644
index 000000000..3ffbea217
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-repeat.rs
@@ -0,0 +1,12 @@
+macro_rules! mac {
+ ( $($v:tt)* ) => {
+ $v
+ //~^ ERROR still repeating at this depth
+ //~| ERROR still repeating at this depth
+ };
+}
+
+fn main() {
+ mac!(0);
+ mac!(1);
+}
diff --git a/src/test/ui/parser/macro/macro-repeat.stderr b/src/test/ui/parser/macro/macro-repeat.stderr
new file mode 100644
index 000000000..63554b197
--- /dev/null
+++ b/src/test/ui/parser/macro/macro-repeat.stderr
@@ -0,0 +1,14 @@
+error: variable 'v' is still repeating at this depth
+ --> $DIR/macro-repeat.rs:3:9
+ |
+LL | $v
+ | ^^
+
+error: variable 'v' is still repeating at this depth
+ --> $DIR/macro-repeat.rs:3:9
+ |
+LL | $v
+ | ^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/macro/pub-item-macro.rs b/src/test/ui/parser/macro/pub-item-macro.rs
new file mode 100644
index 000000000..f5f8a01e6
--- /dev/null
+++ b/src/test/ui/parser/macro/pub-item-macro.rs
@@ -0,0 +1,21 @@
+// Issue #14660
+
+macro_rules! priv_x {
+ () => {
+ static x: u32 = 0;
+ };
+}
+
+macro_rules! pub_x { () => {
+ pub priv_x!(); //~ ERROR can't qualify macro invocation with `pub`
+ //~^ HELP remove the visibility
+ //~| HELP try adjusting the macro to put `pub` inside the invocation
+}}
+
+mod foo {
+ pub_x!();
+}
+
+fn main() {
+ let y: u32 = foo::x; //~ ERROR static `x` is private
+}
diff --git a/src/test/ui/parser/macro/pub-item-macro.stderr b/src/test/ui/parser/macro/pub-item-macro.stderr
new file mode 100644
index 000000000..9a2fffcce
--- /dev/null
+++ b/src/test/ui/parser/macro/pub-item-macro.stderr
@@ -0,0 +1,31 @@
+error: can't qualify macro invocation with `pub`
+ --> $DIR/pub-item-macro.rs:10:5
+ |
+LL | pub priv_x!();
+ | ^^^ help: remove the visibility
+...
+LL | pub_x!();
+ | -------- in this macro invocation
+ |
+ = help: try adjusting the macro to put `pub` inside the invocation
+ = note: this error originates in the macro `pub_x` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0603]: static `x` is private
+ --> $DIR/pub-item-macro.rs:20:23
+ |
+LL | let y: u32 = foo::x;
+ | ^ private static
+ |
+note: the static `x` is defined here
+ --> $DIR/pub-item-macro.rs:5:9
+ |
+LL | static x: u32 = 0;
+ | ^^^^^^^^^^^^^^^^^^
+...
+LL | pub_x!();
+ | -------- in this macro invocation
+ = note: this error originates in the macro `priv_x` which comes from the expansion of the macro `pub_x` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/parser/macro/trait-non-item-macros.rs b/src/test/ui/parser/macro/trait-non-item-macros.rs
new file mode 100644
index 000000000..97fb564bf
--- /dev/null
+++ b/src/test/ui/parser/macro/trait-non-item-macros.rs
@@ -0,0 +1,13 @@
+macro_rules! bah {
+ ($a:expr) => {
+ $a
+ }; //~^ ERROR macro expansion ignores token `2` and any following
+}
+
+trait Bar {
+ bah!(2);
+}
+
+fn main() {
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/macro/trait-non-item-macros.stderr b/src/test/ui/parser/macro/trait-non-item-macros.stderr
new file mode 100644
index 000000000..db20e6b24
--- /dev/null
+++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr
@@ -0,0 +1,22 @@
+error: macro expansion ignores token `2` and any following
+ --> $DIR/trait-non-item-macros.rs:3:9
+ |
+LL | $a
+ | ^^
+...
+LL | bah!(2);
+ | ------- caused by the macro expansion here
+ |
+ = note: the usage of `bah!` is likely invalid in trait item context
+
+error[E0308]: mismatched types
+ --> $DIR/trait-non-item-macros.rs:12:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.rs b/src/test/ui/parser/macro/trait-object-macro-matcher.rs
new file mode 100644
index 000000000..560195977
--- /dev/null
+++ b/src/test/ui/parser/macro/trait-object-macro-matcher.rs
@@ -0,0 +1,14 @@
+// A single lifetime is not parsed as a type.
+// `ty` matcher in particular doesn't accept a single lifetime
+
+macro_rules! m {
+ ($t: ty) => {
+ let _: $t;
+ };
+}
+
+fn main() {
+ m!('static);
+ //~^ ERROR lifetime in trait object type must be followed by `+`
+ //~| ERROR at least one trait is required for an object type
+}
diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
new file mode 100644
index 000000000..40082564b
--- /dev/null
+++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
@@ -0,0 +1,15 @@
+error: lifetime in trait object type must be followed by `+`
+ --> $DIR/trait-object-macro-matcher.rs:11:8
+ |
+LL | m!('static);
+ | ^^^^^^^
+
+error[E0224]: at least one trait is required for an object type
+ --> $DIR/trait-object-macro-matcher.rs:11:8
+ |
+LL | m!('static);
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0224`.
diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs
new file mode 100644
index 000000000..3afc275d6
--- /dev/null
+++ b/src/test/ui/parser/macros-no-semicolon-items.rs
@@ -0,0 +1,15 @@
+macro_rules! foo() //~ ERROR semicolon
+ //~| ERROR unexpected end of macro
+
+macro_rules! bar {
+ ($($tokens:tt)*) => {}
+}
+
+bar!( //~ ERROR semicolon
+ blah
+ blah
+ blah
+)
+
+fn main() {
+}
diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr
new file mode 100644
index 000000000..6d2431c4a
--- /dev/null
+++ b/src/test/ui/parser/macros-no-semicolon-items.stderr
@@ -0,0 +1,47 @@
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+ --> $DIR/macros-no-semicolon-items.rs:1:17
+ |
+LL | macro_rules! foo()
+ | ^^
+ |
+help: change the delimiters to curly braces
+ |
+LL | macro_rules! foo{}
+ | ~~
+help: add a semicolon
+ |
+LL | macro_rules! foo();
+ | +
+
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+ --> $DIR/macros-no-semicolon-items.rs:8:5
+ |
+LL | bar!(
+ | _____^
+LL | | blah
+LL | | blah
+LL | | blah
+LL | | )
+ | |_^
+ |
+help: change the delimiters to curly braces
+ |
+LL ~ bar!{
+LL | blah
+LL | blah
+LL | blah
+LL + }
+ |
+help: add a semicolon
+ |
+LL | );
+ | +
+
+error: unexpected end of macro invocation
+ --> $DIR/macros-no-semicolon-items.rs:1:1
+ |
+LL | macro_rules! foo()
+ | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/macros-no-semicolon.rs b/src/test/ui/parser/macros-no-semicolon.rs
new file mode 100644
index 000000000..24d1ae9e6
--- /dev/null
+++ b/src/test/ui/parser/macros-no-semicolon.rs
@@ -0,0 +1,5 @@
+fn main() {
+ assert_eq!(1, 2) //~ ERROR: expected `;`
+ assert_eq!(3, 4) //~ ERROR: expected `;`
+ println!("hello");
+}
diff --git a/src/test/ui/parser/macros-no-semicolon.stderr b/src/test/ui/parser/macros-no-semicolon.stderr
new file mode 100644
index 000000000..f310662db
--- /dev/null
+++ b/src/test/ui/parser/macros-no-semicolon.stderr
@@ -0,0 +1,18 @@
+error: expected `;`, found `assert_eq`
+ --> $DIR/macros-no-semicolon.rs:2:21
+ |
+LL | assert_eq!(1, 2)
+ | ^ help: add `;` here
+LL | assert_eq!(3, 4)
+ | --------- unexpected token
+
+error: expected `;`, found `println`
+ --> $DIR/macros-no-semicolon.rs:3:21
+ |
+LL | assert_eq!(3, 4)
+ | ^ help: add `;` here
+LL | println!("hello");
+ | ------- unexpected token
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/match-arm-without-braces.rs b/src/test/ui/parser/match-arm-without-braces.rs
new file mode 100644
index 000000000..bba38fd0f
--- /dev/null
+++ b/src/test/ui/parser/match-arm-without-braces.rs
@@ -0,0 +1,87 @@
+struct S;
+
+impl S {
+ fn get<K, V: Default>(_: K) -> Option<V> {
+ Default::default()
+ }
+}
+
+enum Val {
+ Foo,
+ Bar,
+}
+
+impl Default for Val {
+ fn default() -> Self {
+ Val::Foo
+ }
+}
+
+fn main() {
+ match S::get(1) {
+ Some(Val::Foo) => {}
+ _ => {}
+ }
+ match S::get(2) {
+ Some(Val::Foo) => 3; //~ ERROR `match` arm body without braces
+ _ => 4,
+ }
+ match S::get(5) {
+ Some(Val::Foo) =>
+ 7; //~ ERROR `match` arm body without braces
+ 8;
+ _ => 9,
+ }
+ match S::get(10) {
+ Some(Val::Foo) =>
+ 11; //~ ERROR `match` arm body without braces
+ 12;
+ _ => (),
+ }
+ match S::get(13) {
+ None => {}
+ Some(Val::Foo) =>
+ 14; //~ ERROR `match` arm body without braces
+ 15;
+ }
+ match S::get(16) {
+ Some(Val::Foo) => 17 //~ ERROR expected `,` following `match` arm
+ _ => 18,
+ };
+ match S::get(19) {
+ Some(Val::Foo) =>
+ 20; //~ ERROR `match` arm body without braces
+ 21
+ _ => 22,
+ }
+ match S::get(23) {
+ Some(Val::Foo) =>
+ 24; //~ ERROR `match` arm body without braces
+ 25
+ _ => (),
+ }
+ match S::get(26) {
+ None => {}
+ Some(Val::Foo) =>
+ 27; //~ ERROR `match` arm body without braces
+ 28
+ }
+ match S::get(29) {
+ Some(Val::Foo) =>
+ 30; //~ ERROR expected one of
+ 31,
+ _ => 32,
+ }
+ match S::get(33) {
+ Some(Val::Foo) =>
+ 34; //~ ERROR expected one of
+ 35,
+ _ => (),
+ }
+ match S::get(36) {
+ None => {}
+ Some(Val::Foo) =>
+ 37; //~ ERROR expected one of
+ 38,
+ }
+}
diff --git a/src/test/ui/parser/match-arm-without-braces.stderr b/src/test/ui/parser/match-arm-without-braces.stderr
new file mode 100644
index 000000000..37d55aa53
--- /dev/null
+++ b/src/test/ui/parser/match-arm-without-braces.stderr
@@ -0,0 +1,131 @@
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:26:27
+ |
+LL | Some(Val::Foo) => 3;
+ | -- ^- help: use a comma to end a `match` arm expression: `,`
+ | | |
+ | | this statement is not surrounded by a body
+ | while parsing the `match` arm starting here
+
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:31:11
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | / 7;
+LL | | 8;
+ | |____________^ these statements are not surrounded by a body
+ |
+help: surround the statements with a body
+ |
+LL ~ { 7;
+LL ~ 8; }
+ |
+
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:37:11
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | / 11;
+LL | | 12;
+ | |_____________^ these statements are not surrounded by a body
+ |
+help: surround the statements with a body
+ |
+LL ~ { 11;
+LL ~ 12; }
+ |
+
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:44:11
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | / 14;
+LL | | 15;
+ | |_____________^ these statements are not surrounded by a body
+ |
+help: surround the statements with a body
+ |
+LL ~ { 14;
+LL ~ 15; }
+ |
+
+error: expected `,` following `match` arm
+ --> $DIR/match-arm-without-braces.rs:48:29
+ |
+LL | Some(Val::Foo) => 17
+ | ^ help: missing a comma here to end this `match` arm: `,`
+
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:53:11
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | / 20;
+LL | | 21
+ | |____________^ these statements are not surrounded by a body
+ |
+help: surround the statements with a body
+ |
+LL ~ { 20;
+LL ~ 21 }
+ |
+
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:59:11
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | / 24;
+LL | | 25
+ | |____________^ these statements are not surrounded by a body
+ |
+help: surround the statements with a body
+ |
+LL ~ { 24;
+LL ~ 25 }
+ |
+
+error: `match` arm body without braces
+ --> $DIR/match-arm-without-braces.rs:66:11
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | / 27;
+LL | | 28
+ | |____________^ these statements are not surrounded by a body
+ |
+help: surround the statements with a body
+ |
+LL ~ { 27;
+LL ~ 28 }
+ |
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
+ --> $DIR/match-arm-without-braces.rs:71:13
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | 30;
+ | ^ expected one of `,`, `.`, `?`, `}`, or an operator
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
+ --> $DIR/match-arm-without-braces.rs:77:13
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | 34;
+ | ^ expected one of `,`, `.`, `?`, `}`, or an operator
+
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `;`
+ --> $DIR/match-arm-without-braces.rs:84:13
+ |
+LL | Some(Val::Foo) =>
+ | -- while parsing the `match` arm starting here
+LL | 37;
+ | ^ expected one of `,`, `.`, `?`, `}`, or an operator
+
+error: aborting due to 11 previous errors
+
diff --git a/src/test/ui/parser/match-arrows-block-then-binop.rs b/src/test/ui/parser/match-arrows-block-then-binop.rs
new file mode 100644
index 000000000..56c917c74
--- /dev/null
+++ b/src/test/ui/parser/match-arrows-block-then-binop.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let _ = match 0 {
+ 0 => {
+ 0
+ } + 5 //~ ERROR expected pattern, found `+`
+ };
+}
diff --git a/src/test/ui/parser/match-arrows-block-then-binop.stderr b/src/test/ui/parser/match-arrows-block-then-binop.stderr
new file mode 100644
index 000000000..cb361a3db
--- /dev/null
+++ b/src/test/ui/parser/match-arrows-block-then-binop.stderr
@@ -0,0 +1,15 @@
+error: expected pattern, found `+`
+ --> $DIR/match-arrows-block-then-binop.rs:5:9
+ |
+LL | } + 5
+ | ^ expected pattern
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL ~ 0 => ({
+LL | 0
+LL ~ }) + 5
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/match-refactor-to-expr.fixed b/src/test/ui/parser/match-refactor-to-expr.fixed
new file mode 100644
index 000000000..423147b27
--- /dev/null
+++ b/src/test/ui/parser/match-refactor-to-expr.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+
+fn main() {
+ let foo =
+ //~ NOTE while parsing this `match` expression
+ Some(4).unwrap_or(5)
+ //~^ NOTE expected one of `.`, `?`, `{`, or an operator
+ ; //~ NOTE unexpected token
+ //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
+
+ println!("{}", foo)
+}
diff --git a/src/test/ui/parser/match-refactor-to-expr.rs b/src/test/ui/parser/match-refactor-to-expr.rs
new file mode 100644
index 000000000..fcba5d044
--- /dev/null
+++ b/src/test/ui/parser/match-refactor-to-expr.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+
+fn main() {
+ let foo =
+ match //~ NOTE while parsing this `match` expression
+ Some(4).unwrap_or(5)
+ //~^ NOTE expected one of `.`, `?`, `{`, or an operator
+ ; //~ NOTE unexpected token
+ //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
+
+ println!("{}", foo)
+}
diff --git a/src/test/ui/parser/match-refactor-to-expr.stderr b/src/test/ui/parser/match-refactor-to-expr.stderr
new file mode 100644
index 000000000..851bef8f2
--- /dev/null
+++ b/src/test/ui/parser/match-refactor-to-expr.stderr
@@ -0,0 +1,16 @@
+error: expected one of `.`, `?`, `{`, or an operator, found `;`
+ --> $DIR/match-refactor-to-expr.rs:8:9
+ |
+LL | match
+ | -----
+ | |
+ | while parsing this `match` expression
+ | help: try removing this `match`
+LL | Some(4).unwrap_or(5)
+ | - expected one of `.`, `?`, `{`, or an operator
+LL |
+LL | ;
+ | ^ unexpected token
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/mbe_missing_right_paren.rs b/src/test/ui/parser/mbe_missing_right_paren.rs
new file mode 100644
index 000000000..689176b3e
--- /dev/null
+++ b/src/test/ui/parser/mbe_missing_right_paren.rs
@@ -0,0 +1,3 @@
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 3 previous errors
+macro_rules! abc(ؼ \ No newline at end of file
diff --git a/src/test/ui/parser/mbe_missing_right_paren.stderr b/src/test/ui/parser/mbe_missing_right_paren.stderr
new file mode 100644
index 000000000..ccaf77d39
--- /dev/null
+++ b/src/test/ui/parser/mbe_missing_right_paren.stderr
@@ -0,0 +1,31 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/mbe_missing_right_paren.rs:3:19
+ |
+LL | macro_rules! abc(ؼ
+ | - ^
+ | |
+ | unclosed delimiter
+
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+ --> $DIR/mbe_missing_right_paren.rs:3:17
+ |
+LL | macro_rules! abc(ؼ
+ | ^^
+ |
+help: change the delimiters to curly braces
+ |
+LL | macro_rules! abc { /* items */ }
+ | ~~~~~~~~~~~~~~~
+help: add a semicolon
+ |
+LL | macro_rules! abc(ؼ;
+ | +
+
+error: unexpected end of macro invocation
+ --> $DIR/mbe_missing_right_paren.rs:3:19
+ |
+LL | macro_rules! abc(ؼ
+ | ^ missing tokens in macro arguments
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs
new file mode 100644
index 000000000..8f46970b1
--- /dev/null
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs
@@ -0,0 +1,13 @@
+fn main() {}
+
+impl T for () { //~ ERROR cannot find trait `T` in this scope
+
+fn foo(&self) {}
+
+trait T { //~ ERROR trait is not supported in `trait`s or `impl`s
+ fn foo(&self);
+}
+
+pub(crate) struct Bar<T>(); //~ ERROR struct is not supported in `trait`s or `impl`s
+
+//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
new file mode 100644
index 000000000..cc7cc0c55
--- /dev/null
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
@@ -0,0 +1,34 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/missing-close-brace-in-impl-trait.rs:13:52
+ |
+LL | impl T for () {
+ | - unclosed delimiter
+...
+LL |
+ | ^
+
+error: trait is not supported in `trait`s or `impl`s
+ --> $DIR/missing-close-brace-in-impl-trait.rs:7:1
+ |
+LL | trait T {
+ | ^^^^^^^
+ |
+ = help: consider moving the trait out to a nearby module scope
+
+error: struct is not supported in `trait`s or `impl`s
+ --> $DIR/missing-close-brace-in-impl-trait.rs:11:1
+ |
+LL | pub(crate) struct Bar<T>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error[E0405]: cannot find trait `T` in this scope
+ --> $DIR/missing-close-brace-in-impl-trait.rs:3:6
+ |
+LL | impl T for () {
+ | ^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs
new file mode 100644
index 000000000..090a17b41
--- /dev/null
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs
@@ -0,0 +1,13 @@
+pub(crate) struct Bar<T> {
+ foo: T,
+
+trait T { //~ ERROR expected identifier, found keyword `trait`
+ fn foo(&self);
+}
+
+
+impl T for Bar<usize> {
+fn foo(&self) {}
+}
+
+fn main() {} //~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
new file mode 100644
index 000000000..a47d5506e
--- /dev/null
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
@@ -0,0 +1,17 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/missing-close-brace-in-struct.rs:13:65
+ |
+LL | pub(crate) struct Bar<T> {
+ | - unclosed delimiter
+...
+LL | fn main() {}
+ | ^
+
+error: expected identifier, found keyword `trait`
+ --> $DIR/missing-close-brace-in-struct.rs:4:1
+ |
+LL | trait T {
+ | ^^^^^ expected identifier, found keyword
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs
new file mode 100644
index 000000000..b6932deb5
--- /dev/null
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs
@@ -0,0 +1,12 @@
+trait T {
+ fn foo(&self);
+
+pub(crate) struct Bar<T>();
+//~^ ERROR struct is not supported in `trait`s or `impl`s
+
+impl T for Bar<usize> {
+//~^ ERROR implementation is not supported in `trait`s or `impl`s
+fn foo(&self) {}
+}
+
+fn main() {} //~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
new file mode 100644
index 000000000..7c6254356
--- /dev/null
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
@@ -0,0 +1,27 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/missing-close-brace-in-trait.rs:12:65
+ |
+LL | trait T {
+ | - unclosed delimiter
+...
+LL | fn main() {}
+ | ^
+
+error: struct is not supported in `trait`s or `impl`s
+ --> $DIR/missing-close-brace-in-trait.rs:4:1
+ |
+LL | pub(crate) struct Bar<T>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the struct out to a nearby module scope
+
+error: implementation is not supported in `trait`s or `impl`s
+ --> $DIR/missing-close-brace-in-trait.rs:7:1
+ |
+LL | impl T for Bar<usize> {
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider moving the implementation out to a nearby module scope
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.rs b/src/test/ui/parser/mismatched-delim-brace-empty-block.rs
new file mode 100644
index 000000000..61d7a9af2
--- /dev/null
+++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.rs
@@ -0,0 +1,5 @@
+fn main() {
+
+}
+ let _ = ();
+} //~ ERROR unexpected closing delimiter
diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr
new file mode 100644
index 000000000..165eb8ae9
--- /dev/null
+++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr
@@ -0,0 +1,14 @@
+error: unexpected closing delimiter: `}`
+ --> $DIR/mismatched-delim-brace-empty-block.rs:5:1
+ |
+LL | fn main() {
+ | - this opening brace...
+LL |
+LL | }
+ | - ...matches this closing brace
+LL | let _ = ();
+LL | }
+ | ^ unexpected closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs
new file mode 100644
index 000000000..da95c1bfa
--- /dev/null
+++ b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.rs
@@ -0,0 +1,23 @@
+struct Foo<T1, T2> {
+ _a : T1,
+ _b : T2,
+}
+
+fn test1<T>(arg : T) {
+ let v : Vec<(u32,_) = vec![];
+ //~^ ERROR: expected one of
+ //~| ERROR: type annotations needed
+}
+
+fn test2<T1, T2>(arg1 : T1, arg2 : T2) {
+ let foo : Foo::<T1, T2 = Foo {_a : arg1, _b : arg2};
+ //~^ ERROR: expected one of
+}
+
+fn test3<'a>(arg : &'a u32) {
+ let v : Vec<'a = vec![];
+ //~^ ERROR: expected one of
+ //~| ERROR: type annotations needed for `Vec<T>`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr
new file mode 100644
index 000000000..bad241634
--- /dev/null
+++ b/src/test/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr
@@ -0,0 +1,66 @@
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:23
+ |
+LL | let v : Vec<(u32,_) = vec![];
+ | - - ^ expected one of `,`, `:`, or `>`
+ | | |
+ | | maybe try to close unmatched angle bracket
+ | while parsing the type for `v`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | let v : Vec<(u32,_)> = vec![];
+ | +
+
+error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `{`
+ --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:13:32
+ |
+LL | let foo : Foo::<T1, T2 = Foo {_a : arg1, _b : arg2};
+ | --- ^ expected one of 7 possible tokens
+ | |
+ | while parsing the type for `foo`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | let foo : Foo::<T1>, T2 = Foo {_a : arg1, _b : arg2};
+ | +
+
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:18
+ |
+LL | let v : Vec<'a = vec![];
+ | - -- ^ expected one of `,`, `:`, or `>`
+ | | |
+ | | maybe try to close unmatched angle bracket
+ | while parsing the type for `v`
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | let v : Vec<'a> = vec![];
+ | +
+
+error[E0282]: type annotations needed for `Vec<T>`
+ --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:7
+ |
+LL | let v : Vec<(u32,_) = vec![];
+ | ^
+ |
+help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
+ |
+LL | let v: Vec<T> : Vec<(u32,_) = vec![];
+ | ++++++++
+
+error[E0282]: type annotations needed for `Vec<T>`
+ --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:7
+ |
+LL | let v : Vec<'a = vec![];
+ | ^
+ |
+help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
+ |
+LL | let v: Vec<T> : Vec<'a = vec![];
+ | ++++++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs
new file mode 100644
index 000000000..d69a56c51
--- /dev/null
+++ b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.rs
@@ -0,0 +1,11 @@
+// run-rustifx
+#![allow(unused)]
+use std::sync::{Arc, Mutex};
+
+pub struct Foo {
+ a: Mutex<usize>,
+ b: Arc<Mutex<usize>, //~ HELP you might have meant to end the type parameters here
+ c: Arc<Mutex<usize>>,
+} //~ ERROR expected one of
+
+fn main() {}
diff --git a/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr
new file mode 100644
index 000000000..46ca1f06b
--- /dev/null
+++ b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr
@@ -0,0 +1,15 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `}`
+ --> $DIR/missing-closing-angle-bracket-struct-field-ty.rs:9:1
+ |
+LL | c: Arc<Mutex<usize>>,
+ | - expected one of `>`, a const expression, lifetime, or type
+LL | }
+ | ^ unexpected token
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | b: Arc<Mutex<usize>>,
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/missing-semicolon.rs b/src/test/ui/parser/missing-semicolon.rs
new file mode 100644
index 000000000..f68d177c0
--- /dev/null
+++ b/src/test/ui/parser/missing-semicolon.rs
@@ -0,0 +1,8 @@
+macro_rules! m {
+ ($($e1:expr),*; $($e2:expr),*) => {
+ $( let x = $e1 )*; //~ ERROR expected one of `.`, `;`, `?`, `else`, or
+ $( println!("{}", $e2) )*;
+ }
+}
+
+fn main() { m!(0, 0; 0, 0); }
diff --git a/src/test/ui/parser/missing-semicolon.stderr b/src/test/ui/parser/missing-semicolon.stderr
new file mode 100644
index 000000000..e0d5e84ec
--- /dev/null
+++ b/src/test/ui/parser/missing-semicolon.stderr
@@ -0,0 +1,13 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found keyword `let`
+ --> $DIR/missing-semicolon.rs:3:12
+ |
+LL | $( let x = $e1 )*;
+ | ^^^ expected one of `.`, `;`, `?`, `else`, or an operator
+...
+LL | fn main() { m!(0, 0; 0, 0); }
+ | -------------- in this macro invocation
+ |
+ = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/missing_right_paren.rs b/src/test/ui/parser/missing_right_paren.rs
new file mode 100644
index 000000000..810dee957
--- /dev/null
+++ b/src/test/ui/parser/missing_right_paren.rs
@@ -0,0 +1,3 @@
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 4 previous errors
+fn main((ؼ \ No newline at end of file
diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr
new file mode 100644
index 000000000..3fe0d0f42
--- /dev/null
+++ b/src/test/ui/parser/missing_right_paren.stderr
@@ -0,0 +1,32 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/missing_right_paren.rs:3:11
+ |
+LL | fn main((ؼ
+ | -- ^
+ | ||
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/missing_right_paren.rs:3:11
+ |
+LL | fn main((ؼ
+ | -- ^
+ | ||
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: expected one of `:` or `|`, found `)`
+ --> $DIR/missing_right_paren.rs:3:11
+ |
+LL | fn main((ؼ
+ | ^ expected one of `:` or `|`
+
+error: expected one of `->`, `where`, or `{`, found `<eof>`
+ --> $DIR/missing_right_paren.rs:3:11
+ |
+LL | fn main((ؼ
+ | ^ expected one of `->`, `where`, or `{`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/misspelled-macro-rules.fixed b/src/test/ui/parser/misspelled-macro-rules.fixed
new file mode 100644
index 000000000..62be913d8
--- /dev/null
+++ b/src/test/ui/parser/misspelled-macro-rules.fixed
@@ -0,0 +1,13 @@
+// Regression test for issue #91227.
+
+// run-rustfix
+
+#![allow(unused_macros)]
+
+macro_rules! thing {
+//~^ ERROR: expected one of
+//~| HELP: perhaps you meant to define a macro
+ () => {}
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/misspelled-macro-rules.rs b/src/test/ui/parser/misspelled-macro-rules.rs
new file mode 100644
index 000000000..4290e6e5e
--- /dev/null
+++ b/src/test/ui/parser/misspelled-macro-rules.rs
@@ -0,0 +1,13 @@
+// Regression test for issue #91227.
+
+// run-rustfix
+
+#![allow(unused_macros)]
+
+marco_rules! thing {
+//~^ ERROR: expected one of
+//~| HELP: perhaps you meant to define a macro
+ () => {}
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/misspelled-macro-rules.stderr b/src/test/ui/parser/misspelled-macro-rules.stderr
new file mode 100644
index 000000000..56df71238
--- /dev/null
+++ b/src/test/ui/parser/misspelled-macro-rules.stderr
@@ -0,0 +1,10 @@
+error: expected one of `(`, `[`, or `{`, found `thing`
+ --> $DIR/misspelled-macro-rules.rs:7:14
+ |
+LL | marco_rules! thing {
+ | ----------- ^^^^^ expected one of `(`, `[`, or `{`
+ | |
+ | help: perhaps you meant to define a macro: `macro_rules`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/mod_file_not_exist.rs b/src/test/ui/parser/mod_file_not_exist.rs
new file mode 100644
index 000000000..7b079eb02
--- /dev/null
+++ b/src/test/ui/parser/mod_file_not_exist.rs
@@ -0,0 +1,9 @@
+// ignore-windows
+
+mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
+//~^ HELP to create the module `not_a_real_file`, create file
+
+fn main() {
+ assert_eq!(mod_file_aux::bar(), 10);
+ //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux`
+}
diff --git a/src/test/ui/parser/mod_file_not_exist.stderr b/src/test/ui/parser/mod_file_not_exist.stderr
new file mode 100644
index 000000000..62456d518
--- /dev/null
+++ b/src/test/ui/parser/mod_file_not_exist.stderr
@@ -0,0 +1,18 @@
+error[E0583]: file not found for module `not_a_real_file`
+ --> $DIR/mod_file_not_exist.rs:3:1
+ |
+LL | mod not_a_real_file;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs"
+
+error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux`
+ --> $DIR/mod_file_not_exist.rs:7:16
+ |
+LL | assert_eq!(mod_file_aux::bar(), 10);
+ | ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0433, E0583.
+For more information about an error, try `rustc --explain E0433`.
diff --git a/src/test/ui/parser/mod_file_not_exist_windows.rs b/src/test/ui/parser/mod_file_not_exist_windows.rs
new file mode 100644
index 000000000..5db21e2bb
--- /dev/null
+++ b/src/test/ui/parser/mod_file_not_exist_windows.rs
@@ -0,0 +1,9 @@
+// only-windows
+
+mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
+//~^ HELP to create the module `not_a_real_file`, create file
+
+fn main() {
+ assert_eq!(mod_file_aux::bar(), 10);
+ //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux`
+}
diff --git a/src/test/ui/parser/mod_file_not_exist_windows.stderr b/src/test/ui/parser/mod_file_not_exist_windows.stderr
new file mode 100644
index 000000000..d5143dbe9
--- /dev/null
+++ b/src/test/ui/parser/mod_file_not_exist_windows.stderr
@@ -0,0 +1,18 @@
+error[E0583]: file not found for module `not_a_real_file`
+ --> $DIR/mod_file_not_exist_windows.rs:3:1
+ |
+LL | mod not_a_real_file;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs"
+
+error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux`
+ --> $DIR/mod_file_not_exist_windows.rs:7:16
+ |
+LL | assert_eq!(mod_file_aux::bar(), 10);
+ | ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0433, E0583.
+For more information about an error, try `rustc --explain E0433`.
diff --git a/src/test/ui/parser/mod_file_with_path_attr.rs b/src/test/ui/parser/mod_file_with_path_attr.rs
new file mode 100644
index 000000000..9450d89e5
--- /dev/null
+++ b/src/test/ui/parser/mod_file_with_path_attr.rs
@@ -0,0 +1,8 @@
+// normalize-stderr-test: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG ("
+
+#[path = "not_a_real_file.rs"]
+mod m; //~ ERROR not_a_real_file.rs
+
+fn main() {
+ assert_eq!(m::foo(), 10);
+}
diff --git a/src/test/ui/parser/mod_file_with_path_attr.stderr b/src/test/ui/parser/mod_file_with_path_attr.stderr
new file mode 100644
index 000000000..cd1add73d
--- /dev/null
+++ b/src/test/ui/parser/mod_file_with_path_attr.stderr
@@ -0,0 +1,8 @@
+error: couldn't read $DIR/not_a_real_file.rs: $FILE_NOT_FOUND_MSG (os error 2)
+ --> $DIR/mod_file_with_path_attr.rs:4:1
+ |
+LL | mod m;
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs
new file mode 100644
index 000000000..7e7995d67
--- /dev/null
+++ b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs
@@ -0,0 +1,10 @@
+// Regression test for #80134.
+
+fn main() {
+ (()é);
+ //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator
+ //~| ERROR: cannot find value `é` in this scope
+ (()氷);
+ //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator
+ //~| ERROR: cannot find value `氷` in this scope
+}
diff --git a/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr
new file mode 100644
index 000000000..21e71aa12
--- /dev/null
+++ b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr
@@ -0,0 +1,33 @@
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `é`
+ --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
+ |
+LL | (()é);
+ | ^
+ | |
+ | expected one of `)`, `,`, `.`, `?`, or an operator
+ | help: missing `,`
+
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `氷`
+ --> $DIR/multibyte-char-use-seperator-issue-80134.rs:7:8
+ |
+LL | (()氷);
+ | -^
+ | |
+ | expected one of `)`, `,`, `.`, `?`, or an operator
+ | help: missing `,`
+
+error[E0425]: cannot find value `é` in this scope
+ --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
+ |
+LL | (()é);
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `氷` in this scope
+ --> $DIR/multibyte-char-use-seperator-issue-80134.rs:7:8
+ |
+LL | (()氷);
+ | ^^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/multiline-comment-line-tracking.rs b/src/test/ui/parser/multiline-comment-line-tracking.rs
new file mode 100644
index 000000000..d4735e8a7
--- /dev/null
+++ b/src/test/ui/parser/multiline-comment-line-tracking.rs
@@ -0,0 +1,9 @@
+// Parse error on line X, but is reported on line Y instead.
+
+/* 1
+ * 2
+ * 3
+ */
+fn main() {
+ %; //~ ERROR expected expression, found `%`
+}
diff --git a/src/test/ui/parser/multiline-comment-line-tracking.stderr b/src/test/ui/parser/multiline-comment-line-tracking.stderr
new file mode 100644
index 000000000..cac0c801a
--- /dev/null
+++ b/src/test/ui/parser/multiline-comment-line-tracking.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `%`
+ --> $DIR/multiline-comment-line-tracking.rs:8:3
+ |
+LL | %;
+ | ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/multitrait.rs b/src/test/ui/parser/multitrait.rs
new file mode 100644
index 000000000..f9b4b37ac
--- /dev/null
+++ b/src/test/ui/parser/multitrait.rs
@@ -0,0 +1,9 @@
+struct S {
+ y: isize
+}
+
+impl Cmp, ToString for S {
+//~^ ERROR: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,`
+ fn eq(&&other: S) { false }
+ fn to_string(&self) -> String { "hi".to_string() }
+}
diff --git a/src/test/ui/parser/multitrait.stderr b/src/test/ui/parser/multitrait.stderr
new file mode 100644
index 000000000..5a8bb2f7a
--- /dev/null
+++ b/src/test/ui/parser/multitrait.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,`
+ --> $DIR/multitrait.rs:5:9
+ |
+LL | impl Cmp, ToString for S {
+ | ^ expected one of 8 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs
new file mode 100644
index 000000000..8b83d6ab2
--- /dev/null
+++ b/src/test/ui/parser/mut-patterns.rs
@@ -0,0 +1,48 @@
+// Can't put mut in non-ident pattern
+
+// edition:2018
+
+#![feature(box_patterns)]
+#![allow(warnings)]
+
+pub fn main() {
+ let mut _ = 0; //~ ERROR `mut` must be followed by a named binding
+ let mut (_, _) = (0, 0); //~ ERROR `mut` must be followed by a named binding
+
+ let mut (x @ y) = 0; //~ ERROR `mut` must be attached to each individual binding
+
+ let mut mut x = 0;
+ //~^ ERROR `mut` on a binding may not be repeated
+ //~| remove the additional `mut`s
+
+ struct Foo { x: isize }
+ let mut Foo { x: x } = Foo { x: 3 };
+ //~^ ERROR `mut` must be attached to each individual binding
+ //~| add `mut` to each binding
+
+ let mut Foo { x } = Foo { x: 3 };
+ //~^ ERROR `mut` must be attached to each individual binding
+ //~| add `mut` to each binding
+
+ struct r#yield(u8, u8);
+ let mut mut yield(become, await) = r#yield(0, 0);
+ //~^ ERROR `mut` on a binding may not be repeated
+ //~| ERROR `mut` must be attached to each individual binding
+ //~| ERROR expected identifier, found reserved keyword `yield`
+ //~| ERROR expected identifier, found reserved keyword `become`
+ //~| ERROR expected identifier, found keyword `await`
+
+ struct W<T, U>(T, U);
+ struct B { f: Box<u8> }
+ let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
+ //~^ ERROR `mut` must be attached to each individual binding
+ = W(0, W(1, W(2, W(3, B { f: Box::new(4u8) }))));
+
+ // Make sure we don't accidentally allow `mut $p` where `$p:pat`.
+ macro_rules! foo {
+ ($p:pat) => {
+ let mut $p = 0; //~ ERROR expected identifier, found `x`
+ }
+ }
+ foo!(x);
+}
diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr
new file mode 100644
index 000000000..f179d8c9e
--- /dev/null
+++ b/src/test/ui/parser/mut-patterns.stderr
@@ -0,0 +1,114 @@
+error: `mut` must be followed by a named binding
+ --> $DIR/mut-patterns.rs:9:9
+ |
+LL | let mut _ = 0;
+ | ^^^^^ help: remove the `mut` prefix: `_`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` must be followed by a named binding
+ --> $DIR/mut-patterns.rs:10:9
+ |
+LL | let mut (_, _) = (0, 0);
+ | ^^^^^^^^^^ help: remove the `mut` prefix: `(_, _)`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` must be attached to each individual binding
+ --> $DIR/mut-patterns.rs:12:9
+ |
+LL | let mut (x @ y) = 0;
+ | ^^^^^^^^^^^ help: add `mut` to each binding: `(mut x @ mut y)`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` on a binding may not be repeated
+ --> $DIR/mut-patterns.rs:14:13
+ |
+LL | let mut mut x = 0;
+ | ^^^ help: remove the additional `mut`s
+
+error: `mut` must be attached to each individual binding
+ --> $DIR/mut-patterns.rs:19:9
+ |
+LL | let mut Foo { x: x } = Foo { x: 3 };
+ | ^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { x: mut x }`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` must be attached to each individual binding
+ --> $DIR/mut-patterns.rs:23:9
+ |
+LL | let mut Foo { x } = Foo { x: 3 };
+ | ^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { mut x }`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` on a binding may not be repeated
+ --> $DIR/mut-patterns.rs:28:13
+ |
+LL | let mut mut yield(become, await) = r#yield(0, 0);
+ | ^^^ help: remove the additional `mut`s
+
+error: expected identifier, found reserved keyword `yield`
+ --> $DIR/mut-patterns.rs:28:17
+ |
+LL | let mut mut yield(become, await) = r#yield(0, 0);
+ | ^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `yield` to use it as an identifier
+ |
+LL | let mut mut r#yield(become, await) = r#yield(0, 0);
+ | ++
+
+error: expected identifier, found reserved keyword `become`
+ --> $DIR/mut-patterns.rs:28:23
+ |
+LL | let mut mut yield(become, await) = r#yield(0, 0);
+ | ^^^^^^ expected identifier, found reserved keyword
+ |
+help: escape `become` to use it as an identifier
+ |
+LL | let mut mut yield(r#become, await) = r#yield(0, 0);
+ | ++
+
+error: expected identifier, found keyword `await`
+ --> $DIR/mut-patterns.rs:28:31
+ |
+LL | let mut mut yield(become, await) = r#yield(0, 0);
+ | ^^^^^ expected identifier, found keyword
+ |
+help: escape `await` to use it as an identifier
+ |
+LL | let mut mut yield(become, r#await) = r#yield(0, 0);
+ | ++
+
+error: `mut` must be attached to each individual binding
+ --> $DIR/mut-patterns.rs:28:9
+ |
+LL | let mut mut yield(become, await) = r#yield(0, 0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `r#yield(mut r#become, mut r#await)`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` must be attached to each individual binding
+ --> $DIR/mut-patterns.rs:37:9
+ |
+LL | let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
+ |
+ = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: expected identifier, found `x`
+ --> $DIR/mut-patterns.rs:44:21
+ |
+LL | let mut $p = 0;
+ | ^^ expected identifier
+...
+LL | foo!(x);
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 13 previous errors
+
diff --git a/src/test/ui/parser/nested-missing-closing-angle-bracket.rs b/src/test/ui/parser/nested-missing-closing-angle-bracket.rs
new file mode 100644
index 000000000..84ffdd176
--- /dev/null
+++ b/src/test/ui/parser/nested-missing-closing-angle-bracket.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let v : Vec::<Vec<(u32,_,_)> = vec![vec![]];
+ //~^ ERROR: expected one of
+}
diff --git a/src/test/ui/parser/nested-missing-closing-angle-bracket.stderr b/src/test/ui/parser/nested-missing-closing-angle-bracket.stderr
new file mode 100644
index 000000000..b85bc0256
--- /dev/null
+++ b/src/test/ui/parser/nested-missing-closing-angle-bracket.stderr
@@ -0,0 +1,8 @@
+error: expected one of `,` or `>`, found `;`
+ --> $DIR/nested-missing-closing-angle-bracket.rs:2:46
+ |
+LL | let v : Vec::<Vec<(u32,_,_)> = vec![vec![]];
+ | - while parsing the type for `v` ^ expected one of `,` or `>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/new-unicode-escapes-1.rs b/src/test/ui/parser/new-unicode-escapes-1.rs
new file mode 100644
index 000000000..d6a54660e
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-1.rs
@@ -0,0 +1,3 @@
+pub fn main() {
+ let s = "\u{2603"; //~ ERROR unterminated unicode escape
+}
diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr
new file mode 100644
index 000000000..d133e46b4
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-1.stderr
@@ -0,0 +1,13 @@
+error: unterminated unicode escape
+ --> $DIR/new-unicode-escapes-1.rs:2:14
+ |
+LL | let s = "\u{2603";
+ | ^^^^^^^ missing a closing `}`
+ |
+help: terminate the unicode escape
+ |
+LL | let s = "\u{2603}";
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/new-unicode-escapes-2.rs b/src/test/ui/parser/new-unicode-escapes-2.rs
new file mode 100644
index 000000000..cbb614c19
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-2.rs
@@ -0,0 +1,3 @@
+pub fn main() {
+ let s = "\u{260311111111}"; //~ ERROR overlong unicode escape
+}
diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr
new file mode 100644
index 000000000..2f3f8c0f9
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-2.stderr
@@ -0,0 +1,8 @@
+error: overlong unicode escape
+ --> $DIR/new-unicode-escapes-2.rs:2:14
+ |
+LL | let s = "\u{260311111111}";
+ | ^^^^^^^^^^^^^^^^ must have at most 6 hex digits
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/new-unicode-escapes-3.rs b/src/test/ui/parser/new-unicode-escapes-3.rs
new file mode 100644
index 000000000..295ab08c0
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-3.rs
@@ -0,0 +1,4 @@
+pub fn main() {
+ let s1 = "\u{d805}"; //~ ERROR invalid unicode character escape
+ let s2 = "\u{ffffff}"; //~ ERROR invalid unicode character escape
+}
diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr
new file mode 100644
index 000000000..f5a0f8fc7
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-3.stderr
@@ -0,0 +1,18 @@
+error: invalid unicode character escape
+ --> $DIR/new-unicode-escapes-3.rs:2:15
+ |
+LL | let s1 = "\u{d805}";
+ | ^^^^^^^^ invalid escape
+ |
+ = help: unicode escape must not be a surrogate
+
+error: invalid unicode character escape
+ --> $DIR/new-unicode-escapes-3.rs:3:15
+ |
+LL | let s2 = "\u{ffffff}";
+ | ^^^^^^^^^^ invalid escape
+ |
+ = help: unicode escape must be at most 10FFFF
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/new-unicode-escapes-4.rs b/src/test/ui/parser/new-unicode-escapes-4.rs
new file mode 100644
index 000000000..79882713e
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-4.rs
@@ -0,0 +1,4 @@
+pub fn main() {
+ let s = "\u{lol}";
+ //~^ ERROR invalid character in unicode escape: `l`
+}
diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr
new file mode 100644
index 000000000..514591af1
--- /dev/null
+++ b/src/test/ui/parser/new-unicode-escapes-4.stderr
@@ -0,0 +1,8 @@
+error: invalid character in unicode escape: `l`
+ --> $DIR/new-unicode-escapes-4.rs:2:17
+ |
+LL | let s = "\u{lol}";
+ | ^ invalid character in unicode escape
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/no-binary-float-literal.rs b/src/test/ui/parser/no-binary-float-literal.rs
new file mode 100644
index 000000000..e07ff6518
--- /dev/null
+++ b/src/test/ui/parser/no-binary-float-literal.rs
@@ -0,0 +1,8 @@
+fn main() {
+ 0b101010f64;
+ //~^ ERROR binary float literal is not supported
+ 0b101.010;
+ //~^ ERROR binary float literal is not supported
+ 0b101p4f64;
+ //~^ ERROR invalid suffix `p4f64` for number literal
+}
diff --git a/src/test/ui/parser/no-binary-float-literal.stderr b/src/test/ui/parser/no-binary-float-literal.stderr
new file mode 100644
index 000000000..cfd448684
--- /dev/null
+++ b/src/test/ui/parser/no-binary-float-literal.stderr
@@ -0,0 +1,22 @@
+error: binary float literal is not supported
+ --> $DIR/no-binary-float-literal.rs:4:5
+ |
+LL | 0b101.010;
+ | ^^^^^^^^^
+
+error: binary float literal is not supported
+ --> $DIR/no-binary-float-literal.rs:2:5
+ |
+LL | 0b101010f64;
+ | ^^^^^^^^^^^ not supported
+
+error: invalid suffix `p4f64` for number literal
+ --> $DIR/no-binary-float-literal.rs:6:5
+ |
+LL | 0b101p4f64;
+ | ^^^^^^^^^^ invalid suffix `p4f64`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.rs b/src/test/ui/parser/no-const-fn-in-extern-block.rs
new file mode 100644
index 000000000..1993124ed
--- /dev/null
+++ b/src/test/ui/parser/no-const-fn-in-extern-block.rs
@@ -0,0 +1,8 @@
+extern "C" {
+ const fn foo();
+ //~^ ERROR functions in `extern` blocks cannot have qualifiers
+ const unsafe fn bar();
+ //~^ ERROR functions in `extern` blocks cannot have qualifiers
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.stderr b/src/test/ui/parser/no-const-fn-in-extern-block.stderr
new file mode 100644
index 000000000..4ac0e2655
--- /dev/null
+++ b/src/test/ui/parser/no-const-fn-in-extern-block.stderr
@@ -0,0 +1,29 @@
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/no-const-fn-in-extern-block.rs:2:14
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+LL | const fn foo();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn foo();
+ | ~~
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/no-const-fn-in-extern-block.rs:4:21
+ |
+LL | extern "C" {
+ | ---------- in this `extern` block
+...
+LL | const unsafe fn bar();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn bar();
+ | ~~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/no-hex-float-literal.rs b/src/test/ui/parser/no-hex-float-literal.rs
new file mode 100644
index 000000000..bf11dee08
--- /dev/null
+++ b/src/test/ui/parser/no-hex-float-literal.rs
@@ -0,0 +1,9 @@
+fn main() {
+ 0xABC.Df;
+ //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields
+ 0x567.89;
+ //~^ ERROR hexadecimal float literal is not supported
+ 0xDEAD.BEEFp-2f;
+ //~^ ERROR invalid suffix `f` for float literal
+ //~| ERROR `{integer}` is a primitive type and therefore doesn't have fields
+}
diff --git a/src/test/ui/parser/no-hex-float-literal.stderr b/src/test/ui/parser/no-hex-float-literal.stderr
new file mode 100644
index 000000000..258ab06d5
--- /dev/null
+++ b/src/test/ui/parser/no-hex-float-literal.stderr
@@ -0,0 +1,29 @@
+error: hexadecimal float literal is not supported
+ --> $DIR/no-hex-float-literal.rs:4:5
+ |
+LL | 0x567.89;
+ | ^^^^^^^^
+
+error: invalid suffix `f` for float literal
+ --> $DIR/no-hex-float-literal.rs:6:18
+ |
+LL | 0xDEAD.BEEFp-2f;
+ | ^^ invalid suffix `f`
+ |
+ = help: valid suffixes are `f32` and `f64`
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/no-hex-float-literal.rs:2:11
+ |
+LL | 0xABC.Df;
+ | ^^
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/no-hex-float-literal.rs:6:12
+ |
+LL | 0xDEAD.BEEFp-2f;
+ | ^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0610`.
diff --git a/src/test/ui/parser/no-unsafe-self.rs b/src/test/ui/parser/no-unsafe-self.rs
new file mode 100644
index 000000000..d1cd8ad53
--- /dev/null
+++ b/src/test/ui/parser/no-unsafe-self.rs
@@ -0,0 +1,14 @@
+trait A {
+ fn foo(*mut self); //~ ERROR cannot pass `self` by raw pointer
+ fn baz(*const self); //~ ERROR cannot pass `self` by raw pointer
+ fn bar(*self); //~ ERROR cannot pass `self` by raw pointer
+}
+
+struct X;
+impl A for X {
+ fn foo(*mut self) { } //~ ERROR cannot pass `self` by raw pointer
+ fn baz(*const self) { } //~ ERROR cannot pass `self` by raw pointer
+ fn bar(*self) { } //~ ERROR cannot pass `self` by raw pointer
+}
+
+fn main() { }
diff --git a/src/test/ui/parser/no-unsafe-self.stderr b/src/test/ui/parser/no-unsafe-self.stderr
new file mode 100644
index 000000000..23323945e
--- /dev/null
+++ b/src/test/ui/parser/no-unsafe-self.stderr
@@ -0,0 +1,38 @@
+error: cannot pass `self` by raw pointer
+ --> $DIR/no-unsafe-self.rs:2:17
+ |
+LL | fn foo(*mut self);
+ | ^^^^ cannot pass `self` by raw pointer
+
+error: cannot pass `self` by raw pointer
+ --> $DIR/no-unsafe-self.rs:3:19
+ |
+LL | fn baz(*const self);
+ | ^^^^ cannot pass `self` by raw pointer
+
+error: cannot pass `self` by raw pointer
+ --> $DIR/no-unsafe-self.rs:4:13
+ |
+LL | fn bar(*self);
+ | ^^^^ cannot pass `self` by raw pointer
+
+error: cannot pass `self` by raw pointer
+ --> $DIR/no-unsafe-self.rs:9:17
+ |
+LL | fn foo(*mut self) { }
+ | ^^^^ cannot pass `self` by raw pointer
+
+error: cannot pass `self` by raw pointer
+ --> $DIR/no-unsafe-self.rs:10:19
+ |
+LL | fn baz(*const self) { }
+ | ^^^^ cannot pass `self` by raw pointer
+
+error: cannot pass `self` by raw pointer
+ --> $DIR/no-unsafe-self.rs:11:13
+ |
+LL | fn bar(*self) { }
+ | ^^^^ cannot pass `self` by raw pointer
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/not-a-pred.rs b/src/test/ui/parser/not-a-pred.rs
new file mode 100644
index 000000000..5518b554d
--- /dev/null
+++ b/src/test/ui/parser/not-a-pred.rs
@@ -0,0 +1,15 @@
+fn f(a: isize, b: isize) : lt(a, b) { }
+//~^ 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));
+ //~^ ERROR cannot find function `check` in this scope [E0425]
+ f(a, b);
+}
diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr
new file mode 100644
index 000000000..bcc64a687
--- /dev/null
+++ b/src/test/ui/parser/not-a-pred.stderr
@@ -0,0 +1,34 @@
+error: return types are denoted using `->`
+ --> $DIR/not-a-pred.rs:1:26
+ |
+LL | fn f(a: isize, b: isize) : lt(a, b) { }
+ | ^ help: use `->` instead
+
+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`.
diff --git a/src/test/ui/parser/nt-parsing-has-recovery.rs b/src/test/ui/parser/nt-parsing-has-recovery.rs
new file mode 100644
index 000000000..ccbeb398a
--- /dev/null
+++ b/src/test/ui/parser/nt-parsing-has-recovery.rs
@@ -0,0 +1,10 @@
+macro_rules! foo {
+ ($e:expr) => {}
+}
+
+foo!(1 + @); //~ ERROR expected expression, found `@`
+foo!(1 + @); //~ ERROR expected expression, found `@`
+
+fn main() {
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/nt-parsing-has-recovery.stderr b/src/test/ui/parser/nt-parsing-has-recovery.stderr
new file mode 100644
index 000000000..263c4ad53
--- /dev/null
+++ b/src/test/ui/parser/nt-parsing-has-recovery.stderr
@@ -0,0 +1,29 @@
+error: expected expression, found `@`
+ --> $DIR/nt-parsing-has-recovery.rs:5:10
+ |
+LL | ($e:expr) => {}
+ | ------- while parsing argument for this `expr` macro fragment
+...
+LL | foo!(1 + @);
+ | ^ expected expression
+
+error: expected expression, found `@`
+ --> $DIR/nt-parsing-has-recovery.rs:6:10
+ |
+LL | ($e:expr) => {}
+ | ------- while parsing argument for this `expr` macro fragment
+...
+LL | foo!(1 + @);
+ | ^ expected expression
+
+error[E0308]: mismatched types
+ --> $DIR/nt-parsing-has-recovery.rs:9:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/numeric-lifetime.rs b/src/test/ui/parser/numeric-lifetime.rs
new file mode 100644
index 000000000..2d82354c6
--- /dev/null
+++ b/src/test/ui/parser/numeric-lifetime.rs
@@ -0,0 +1,8 @@
+struct S<'1> { s: &'1 usize }
+//~^ ERROR lifetimes cannot start with a number
+//~| ERROR lifetimes cannot start with a number
+fn main() {
+ // verify that the parse error doesn't stop type checking
+ let x: usize = "";
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/numeric-lifetime.stderr b/src/test/ui/parser/numeric-lifetime.stderr
new file mode 100644
index 000000000..73a828952
--- /dev/null
+++ b/src/test/ui/parser/numeric-lifetime.stderr
@@ -0,0 +1,23 @@
+error: lifetimes cannot start with a number
+ --> $DIR/numeric-lifetime.rs:1:10
+ |
+LL | struct S<'1> { s: &'1 usize }
+ | ^^
+
+error: lifetimes cannot start with a number
+ --> $DIR/numeric-lifetime.rs:1:20
+ |
+LL | struct S<'1> { s: &'1 usize }
+ | ^^
+
+error[E0308]: mismatched types
+ --> $DIR/numeric-lifetime.rs:6:20
+ |
+LL | let x: usize = "";
+ | ----- ^^ expected `usize`, found `&str`
+ | |
+ | expected due to this
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs
new file mode 100644
index 000000000..e928f09aa
--- /dev/null
+++ b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.rs
@@ -0,0 +1,9 @@
+trait Trait1 {}
+trait Trait2 {}
+
+#[cfg(not_enabled)]
+impl Trait1 for .. {}
+
+impl Trait2 for .. {} //~ ERROR `impl Trait for .. {}` is an obsolete syntax
+
+fn main() {}
diff --git a/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr
new file mode 100644
index 000000000..b7108ced0
--- /dev/null
+++ b/src/test/ui/parser/obsolete-syntax-impl-for-dotdot.stderr
@@ -0,0 +1,10 @@
+error: `impl Trait for .. {}` is an obsolete syntax
+ --> $DIR/obsolete-syntax-impl-for-dotdot.rs:7:1
+ |
+LL | impl Trait2 for .. {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: use `auto trait Trait {}` instead
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/old-suffixes-are-really-forbidden.rs b/src/test/ui/parser/old-suffixes-are-really-forbidden.rs
new file mode 100644
index 000000000..eea95b7d6
--- /dev/null
+++ b/src/test/ui/parser/old-suffixes-are-really-forbidden.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let a = 1_is; //~ ERROR invalid suffix
+ let b = 2_us; //~ ERROR invalid suffix
+}
diff --git a/src/test/ui/parser/old-suffixes-are-really-forbidden.stderr b/src/test/ui/parser/old-suffixes-are-really-forbidden.stderr
new file mode 100644
index 000000000..fb309793b
--- /dev/null
+++ b/src/test/ui/parser/old-suffixes-are-really-forbidden.stderr
@@ -0,0 +1,18 @@
+error: invalid suffix `is` for number literal
+ --> $DIR/old-suffixes-are-really-forbidden.rs:2:13
+ |
+LL | let a = 1_is;
+ | ^^^^ invalid suffix `is`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: invalid suffix `us` for number literal
+ --> $DIR/old-suffixes-are-really-forbidden.rs:3:13
+ |
+LL | let b = 2_us;
+ | ^^^^ invalid suffix `us`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.rs b/src/test/ui/parser/omitted-arg-in-item-fn.rs
new file mode 100644
index 000000000..49cbc4d6b
--- /dev/null
+++ b/src/test/ui/parser/omitted-arg-in-item-fn.rs
@@ -0,0 +1,4 @@
+fn foo(x) { //~ ERROR expected one of `:`, `@`, or `|`, found `)`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.stderr b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
new file mode 100644
index 000000000..ce2eab051
--- /dev/null
+++ b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
@@ -0,0 +1,22 @@
+error: expected one of `:`, `@`, or `|`, found `)`
+ --> $DIR/omitted-arg-in-item-fn.rs:1:9
+ |
+LL | fn foo(x) {
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+ |
+LL | fn foo(self: x) {
+ | +++++
+help: if this is a parameter name, give it a type
+ |
+LL | fn foo(x: TypeName) {
+ | ++++++++++
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn foo(_: x) {
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/operator-associativity.rs b/src/test/ui/parser/operator-associativity.rs
new file mode 100644
index 000000000..4f40c80bc
--- /dev/null
+++ b/src/test/ui/parser/operator-associativity.rs
@@ -0,0 +1,4 @@
+// run-pass
+// Testcase for issue #130, operator associativity.
+
+pub fn main() { assert_eq!(3 * 5 / 2, 7); }
diff --git a/src/test/ui/parser/paamayim-nekudotayim.rs b/src/test/ui/parser/paamayim-nekudotayim.rs
new file mode 100644
index 000000000..cb151d652
--- /dev/null
+++ b/src/test/ui/parser/paamayim-nekudotayim.rs
@@ -0,0 +1,5 @@
+// http://phpsadness.com/sad/1
+
+fn main() {
+ ::; //~ ERROR expected identifier, found `;`
+}
diff --git a/src/test/ui/parser/paamayim-nekudotayim.stderr b/src/test/ui/parser/paamayim-nekudotayim.stderr
new file mode 100644
index 000000000..6ceba07f4
--- /dev/null
+++ b/src/test/ui/parser/paamayim-nekudotayim.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `;`
+ --> $DIR/paamayim-nekudotayim.rs:4:7
+ |
+LL | ::;
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/parse-assoc-type-lt.rs b/src/test/ui/parser/parse-assoc-type-lt.rs
new file mode 100644
index 000000000..d3fe6079a
--- /dev/null
+++ b/src/test/ui/parser/parse-assoc-type-lt.rs
@@ -0,0 +1,9 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+trait Foo {
+ type T;
+ fn foo() -> Box<<Self as Foo>::T>;
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/parse-error-correct.rs b/src/test/ui/parser/parse-error-correct.rs
new file mode 100644
index 000000000..13759a235
--- /dev/null
+++ b/src/test/ui/parser/parse-error-correct.rs
@@ -0,0 +1,10 @@
+// Test that the parser is error correcting missing idents. Despite a parsing
+// error (or two), we still run type checking (and don't get extra errors there).
+
+fn main() {
+ let y = 42;
+ let x = y.; //~ ERROR unexpected token
+ let x = y.(); //~ ERROR unexpected token
+ //~^ ERROR expected function, found `{integer}`
+ let x = y.foo; //~ ERROR `{integer}` is a primitive type and therefore doesn't have fields [E061
+}
diff --git a/src/test/ui/parser/parse-error-correct.stderr b/src/test/ui/parser/parse-error-correct.stderr
new file mode 100644
index 000000000..691df9126
--- /dev/null
+++ b/src/test/ui/parser/parse-error-correct.stderr
@@ -0,0 +1,33 @@
+error: unexpected token: `;`
+ --> $DIR/parse-error-correct.rs:6:15
+ |
+LL | let x = y.;
+ | ^
+
+error: unexpected token: `(`
+ --> $DIR/parse-error-correct.rs:7:15
+ |
+LL | let x = y.();
+ | ^
+
+error[E0618]: expected function, found `{integer}`
+ --> $DIR/parse-error-correct.rs:7:13
+ |
+LL | let y = 42;
+ | - `y` has type `{integer}`
+LL | let x = y.;
+LL | let x = y.();
+ | ^---
+ | |
+ | call expression requires function
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/parse-error-correct.rs:9:15
+ |
+LL | let x = y.foo;
+ | ^^^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0610, E0618.
+For more information about an error, try `rustc --explain E0610`.
diff --git a/src/test/ui/parser/parse-panic.rs b/src/test/ui/parser/parse-panic.rs
new file mode 100644
index 000000000..aeb2ba4fa
--- /dev/null
+++ b/src/test/ui/parser/parse-panic.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unreachable_code)]
+
+fn dont_call_me() { panic!(); println!("{}", 1); }
+
+pub fn main() { }
diff --git a/src/test/ui/parser/parser-recovery-1.rs b/src/test/ui/parser/parser-recovery-1.rs
new file mode 100644
index 000000000..7e26b4f2b
--- /dev/null
+++ b/src/test/ui/parser/parser-recovery-1.rs
@@ -0,0 +1,13 @@
+// Test that we can recover from missing braces in the parser.
+
+trait Foo {
+ fn bar() {
+ let x = foo();
+ //~^ ERROR cannot find function `foo` in this scope
+}
+
+fn main() {
+ let x = y.;
+ //~^ ERROR unexpected token
+ //~| ERROR cannot find value `y` in this scope
+} //~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/parser-recovery-1.stderr b/src/test/ui/parser/parser-recovery-1.stderr
new file mode 100644
index 000000000..f56060c3e
--- /dev/null
+++ b/src/test/ui/parser/parser-recovery-1.stderr
@@ -0,0 +1,35 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/parser-recovery-1.rs:13:54
+ |
+LL | trait Foo {
+ | - unclosed delimiter
+LL | fn bar() {
+ | - this delimiter might not be properly closed...
+...
+LL | }
+ | - ...as it matches this but it has different indentation
+...
+LL | }
+ | ^
+
+error: unexpected token: `;`
+ --> $DIR/parser-recovery-1.rs:10:15
+ |
+LL | let x = y.;
+ | ^
+
+error[E0425]: cannot find function `foo` in this scope
+ --> $DIR/parser-recovery-1.rs:5:17
+ |
+LL | let x = foo();
+ | ^^^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/parser-recovery-1.rs:10:13
+ |
+LL | let x = y.;
+ | ^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/parser-recovery-2.rs b/src/test/ui/parser/parser-recovery-2.rs
new file mode 100644
index 000000000..48b22afff
--- /dev/null
+++ b/src/test/ui/parser/parser-recovery-2.rs
@@ -0,0 +1,12 @@
+// Test that we can recover from mismatched braces in the parser.
+
+trait Foo {
+ fn bar() {
+ let x = foo(); //~ ERROR cannot find function `foo` in this scope
+ ) //~ ERROR mismatched closing delimiter: `)`
+}
+
+fn main() {
+ let x = y.; //~ ERROR unexpected token
+ //~^ ERROR cannot find value `y` in this scope
+}
diff --git a/src/test/ui/parser/parser-recovery-2.stderr b/src/test/ui/parser/parser-recovery-2.stderr
new file mode 100644
index 000000000..0980d033f
--- /dev/null
+++ b/src/test/ui/parser/parser-recovery-2.stderr
@@ -0,0 +1,30 @@
+error: unexpected token: `;`
+ --> $DIR/parser-recovery-2.rs:10:15
+ |
+LL | let x = y.;
+ | ^
+
+error: mismatched closing delimiter: `)`
+ --> $DIR/parser-recovery-2.rs:4:14
+ |
+LL | fn bar() {
+ | ^ unclosed delimiter
+LL | let x = foo();
+LL | )
+ | ^ mismatched closing delimiter
+
+error[E0425]: cannot find function `foo` in this scope
+ --> $DIR/parser-recovery-2.rs:5:17
+ |
+LL | let x = foo();
+ | ^^^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/parser-recovery-2.rs:10:13
+ |
+LL | let x = y.;
+ | ^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/parser-unicode-whitespace.rs b/src/test/ui/parser/parser-unicode-whitespace.rs
new file mode 100644
index 000000000..555cd68c3
--- /dev/null
+++ b/src/test/ui/parser/parser-unicode-whitespace.rs
@@ -0,0 +1,12 @@
+// run-pass
+// Beware editing: it has numerous whitespace characters which are important.
+// It contains one ranges from the 'PATTERN_WHITE_SPACE' property outlined in
+// https://unicode.org/Public/UNIDATA/PropList.txt
+//
+// The characters in the first expression of the assertion can be generated
+// from: "4\u{0C}+\n\t\r7\t*\u{20}2\u{85}/\u{200E}3\u{200F}*\u{2028}2\u{2029}"
+pub fn main() {
+assert_eq!(4 +
+
+7 * 2…/‎3‏*
2
, 4 + 7 * 2 / 3 * 2);
+}
diff --git a/src/test/ui/parser/pat-lt-bracket-1.rs b/src/test/ui/parser/pat-lt-bracket-1.rs
new file mode 100644
index 000000000..2e2001434
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-1.rs
@@ -0,0 +1,7 @@
+fn main() {
+ match 42 {
+ x < 7 => (),
+ //~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
+ _ => ()
+ }
+}
diff --git a/src/test/ui/parser/pat-lt-bracket-1.stderr b/src/test/ui/parser/pat-lt-bracket-1.stderr
new file mode 100644
index 000000000..e8ccbad66
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-1.stderr
@@ -0,0 +1,8 @@
+error: expected one of `=>`, `@`, `if`, or `|`, found `<`
+ --> $DIR/pat-lt-bracket-1.rs:3:7
+ |
+LL | x < 7 => (),
+ | ^ expected one of `=>`, `@`, `if`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-lt-bracket-2.rs b/src/test/ui/parser/pat-lt-bracket-2.rs
new file mode 100644
index 000000000..3a778ed14
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-2.rs
@@ -0,0 +1,4 @@
+fn a(B<) {}
+ //~^ error: expected one of `:`, `@`, or `|`, found `<`
+
+fn main() {}
diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr
new file mode 100644
index 000000000..c78f96e1a
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-2.stderr
@@ -0,0 +1,18 @@
+error: expected one of `:`, `@`, or `|`, found `<`
+ --> $DIR/pat-lt-bracket-2.rs:1:7
+ |
+LL | fn a(B<) {}
+ | ^ expected one of `:`, `@`, or `|`
+ |
+ = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
+help: if this is a `self` type, give it a parameter name
+ |
+LL | fn a(self: B<) {}
+ | +++++
+help: if this is a type, explicitly ignore the parameter name
+ |
+LL | fn a(_: B<) {}
+ | ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-lt-bracket-3.rs b/src/test/ui/parser/pat-lt-bracket-3.rs
new file mode 100644
index 000000000..a8bdfd3fa
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-3.rs
@@ -0,0 +1,14 @@
+struct Foo<T>(T, T);
+
+impl<T> Foo<T> {
+ fn foo(&self) {
+ match *self {
+ Foo<T>(x, y) => {
+ //~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
+ println!("Goodbye, World!")
+ }
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/pat-lt-bracket-3.stderr b/src/test/ui/parser/pat-lt-bracket-3.stderr
new file mode 100644
index 000000000..bacf868e3
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-3.stderr
@@ -0,0 +1,8 @@
+error: expected one of `=>`, `@`, `if`, or `|`, found `<`
+ --> $DIR/pat-lt-bracket-3.rs:6:16
+ |
+LL | Foo<T>(x, y) => {
+ | ^ expected one of `=>`, `@`, `if`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-lt-bracket-4.rs b/src/test/ui/parser/pat-lt-bracket-4.rs
new file mode 100644
index 000000000..de314f6c6
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-4.rs
@@ -0,0 +1,11 @@
+enum BtNode {
+ Node(u32,Box<BtNode>,Box<BtNode>),
+ Leaf(u32),
+}
+
+fn main() {
+ let y = match 10 {
+ Foo<T>::A(value) => value, //~ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
+ Foo<T>::B => 7,
+ };
+}
diff --git a/src/test/ui/parser/pat-lt-bracket-4.stderr b/src/test/ui/parser/pat-lt-bracket-4.stderr
new file mode 100644
index 000000000..911c276b9
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-4.stderr
@@ -0,0 +1,8 @@
+error: expected one of `=>`, `@`, `if`, or `|`, found `<`
+ --> $DIR/pat-lt-bracket-4.rs:8:12
+ |
+LL | Foo<T>::A(value) => value,
+ | ^ expected one of `=>`, `@`, `if`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-lt-bracket-5.rs b/src/test/ui/parser/pat-lt-bracket-5.rs
new file mode 100644
index 000000000..aaece1f6b
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-5.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let v[0] = v[1]; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+}
diff --git a/src/test/ui/parser/pat-lt-bracket-5.stderr b/src/test/ui/parser/pat-lt-bracket-5.stderr
new file mode 100644
index 000000000..e23674bce
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-5.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+ --> $DIR/pat-lt-bracket-5.rs:2:10
+ |
+LL | let v[0] = v[1];
+ | ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs
new file mode 100644
index 000000000..7becffa9f
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-6.rs
@@ -0,0 +1,9 @@
+fn main() {
+ struct Test(&'static u8, [u8; 0]);
+ let x = Test(&0, []);
+
+ let Test(&desc[..]) = x;
+ //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
+}
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
new file mode 100644
index 000000000..035d0dbfe
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -0,0 +1,18 @@
+error: expected one of `)`, `,`, `@`, or `|`, found `[`
+ --> $DIR/pat-lt-bracket-6.rs:5:19
+ |
+LL | let Test(&desc[..]) = x;
+ | ^
+ | |
+ | expected one of `)`, `,`, `@`, or `|`
+ | help: missing `,`
+
+error[E0308]: mismatched types
+ --> $DIR/pat-lt-bracket-6.rs:9:30
+ |
+LL | const RECOVERY_WITNESS: () = 0;
+ | ^ expected `()`, found integer
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs
new file mode 100644
index 000000000..327aef5ad
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-7.rs
@@ -0,0 +1,9 @@
+fn main() {
+ struct Thing(u8, [u8; 0]);
+ let foo = core::iter::empty();
+
+ for Thing(x[]) in foo {}
+ //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
+}
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr
new file mode 100644
index 000000000..004dcfb2a
--- /dev/null
+++ b/src/test/ui/parser/pat-lt-bracket-7.stderr
@@ -0,0 +1,18 @@
+error: expected one of `)`, `,`, `@`, or `|`, found `[`
+ --> $DIR/pat-lt-bracket-7.rs:5:16
+ |
+LL | for Thing(x[]) in foo {}
+ | ^
+ | |
+ | expected one of `)`, `,`, `@`, or `|`
+ | help: missing `,`
+
+error[E0308]: mismatched types
+ --> $DIR/pat-lt-bracket-7.rs:9:30
+ |
+LL | const RECOVERY_WITNESS: () = 0;
+ | ^ expected `()`, found integer
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-ranges-1.rs b/src/test/ui/parser/pat-ranges-1.rs
new file mode 100644
index 000000000..1dafb5a07
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-1.rs
@@ -0,0 +1,5 @@
+// Parsing of range patterns
+
+fn main() {
+ let macropus!() ..= 11 = 12; //~ error: expected one of `:`, `;`, `=`, or `|`, found `..=`
+}
diff --git a/src/test/ui/parser/pat-ranges-1.stderr b/src/test/ui/parser/pat-ranges-1.stderr
new file mode 100644
index 000000000..b64a3ce5c
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-1.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, or `|`, found `..=`
+ --> $DIR/pat-ranges-1.rs:4:21
+ |
+LL | let macropus!() ..= 11 = 12;
+ | ^^^ expected one of `:`, `;`, `=`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-ranges-2.rs b/src/test/ui/parser/pat-ranges-2.rs
new file mode 100644
index 000000000..1593222ac
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-2.rs
@@ -0,0 +1,5 @@
+// Parsing of range patterns
+
+fn main() {
+ let 10 ..= makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!`
+}
diff --git a/src/test/ui/parser/pat-ranges-2.stderr b/src/test/ui/parser/pat-ranges-2.stderr
new file mode 100644
index 000000000..1a9e33beb
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-2.stderr
@@ -0,0 +1,8 @@
+error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!`
+ --> $DIR/pat-ranges-2.rs:4:26
+ |
+LL | let 10 ..= makropulos!() = 12;
+ | ^ expected one of `::`, `:`, `;`, `=`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-ranges-3.rs b/src/test/ui/parser/pat-ranges-3.rs
new file mode 100644
index 000000000..8976dcf0d
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-3.rs
@@ -0,0 +1,5 @@
+// Parsing of range patterns
+
+fn main() {
+ let 10 ..= 10 + 3 = 12; //~ expected one of `:`, `;`, `=`, or `|`, found `+`
+}
diff --git a/src/test/ui/parser/pat-ranges-3.stderr b/src/test/ui/parser/pat-ranges-3.stderr
new file mode 100644
index 000000000..c9787b789
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-3.stderr
@@ -0,0 +1,8 @@
+error: expected one of `:`, `;`, `=`, or `|`, found `+`
+ --> $DIR/pat-ranges-3.rs:4:19
+ |
+LL | let 10 ..= 10 + 3 = 12;
+ | ^ expected one of `:`, `;`, `=`, or `|`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-ranges-4.rs b/src/test/ui/parser/pat-ranges-4.rs
new file mode 100644
index 000000000..61188976b
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-4.rs
@@ -0,0 +1,6 @@
+// Parsing of range patterns
+
+fn main() {
+ let 10 - 3 ..= 10 = 8;
+ //~^ error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
+}
diff --git a/src/test/ui/parser/pat-ranges-4.stderr b/src/test/ui/parser/pat-ranges-4.stderr
new file mode 100644
index 000000000..69084b5a4
--- /dev/null
+++ b/src/test/ui/parser/pat-ranges-4.stderr
@@ -0,0 +1,8 @@
+error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
+ --> $DIR/pat-ranges-4.rs:4:12
+ |
+LL | let 10 - 3 ..= 10 = 8;
+ | ^ expected one of 7 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-ref-enum.rs b/src/test/ui/parser/pat-ref-enum.rs
new file mode 100644
index 000000000..412dd141d
--- /dev/null
+++ b/src/test/ui/parser/pat-ref-enum.rs
@@ -0,0 +1,8 @@
+fn matcher(x: Option<isize>) {
+ match x {
+ ref Some(i) => {} //~ ERROR expected identifier, found enum pattern
+ None => {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/pat-ref-enum.stderr b/src/test/ui/parser/pat-ref-enum.stderr
new file mode 100644
index 000000000..a3bce3372
--- /dev/null
+++ b/src/test/ui/parser/pat-ref-enum.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found enum pattern
+ --> $DIR/pat-ref-enum.rs:3:11
+ |
+LL | ref Some(i) => {}
+ | ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-tuple-1.rs b/src/test/ui/parser/pat-tuple-1.rs
new file mode 100644
index 000000000..0e49b547f
--- /dev/null
+++ b/src/test/ui/parser/pat-tuple-1.rs
@@ -0,0 +1,5 @@
+fn main() {
+ match (0, 1) {
+ (, ..) => {} //~ ERROR expected pattern, found `,`
+ }
+}
diff --git a/src/test/ui/parser/pat-tuple-1.stderr b/src/test/ui/parser/pat-tuple-1.stderr
new file mode 100644
index 000000000..391f2c428
--- /dev/null
+++ b/src/test/ui/parser/pat-tuple-1.stderr
@@ -0,0 +1,8 @@
+error: expected pattern, found `,`
+ --> $DIR/pat-tuple-1.rs:3:10
+ |
+LL | (, ..) => {}
+ | ^ expected pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs
new file mode 100644
index 000000000..a8f3debd3
--- /dev/null
+++ b/src/test/ui/parser/pat-tuple-2.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+fn main() {
+ match (0, 1, 2) {
+ (pat, ..,) => {}
+ }
+}
diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs
new file mode 100644
index 000000000..1486ab231
--- /dev/null
+++ b/src/test/ui/parser/pat-tuple-3.rs
@@ -0,0 +1,6 @@
+fn main() {
+ match (0, 1, 2) {
+ (.., pat, ..) => {}
+ //~^ ERROR `..` can only be used once per tuple pattern
+ }
+}
diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr
new file mode 100644
index 000000000..9ac0611c5
--- /dev/null
+++ b/src/test/ui/parser/pat-tuple-3.stderr
@@ -0,0 +1,10 @@
+error: `..` can only be used once per tuple pattern
+ --> $DIR/pat-tuple-3.rs:3:19
+ |
+LL | (.., pat, ..) => {}
+ | -- ^^ can only be used once per tuple pattern
+ | |
+ | previously used here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/pub-method-macro.rs b/src/test/ui/parser/pub-method-macro.rs
new file mode 100644
index 000000000..0183bdcf6
--- /dev/null
+++ b/src/test/ui/parser/pub-method-macro.rs
@@ -0,0 +1,23 @@
+// Issue #18317
+
+mod bleh {
+ macro_rules! defn {
+ ($n:ident) => (
+ fn $n (&self) -> i32 {
+ println!("{}", stringify!($n));
+ 1
+ }
+ )
+ }
+
+ #[derive(Copy, Clone)]
+ pub struct S;
+
+ impl S {
+ pub defn!(f); //~ ERROR can't qualify macro invocation with `pub`
+ //~^ HELP remove the visibility
+ //~| HELP try adjusting the macro to put `pub` inside the invocation
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/pub-method-macro.stderr b/src/test/ui/parser/pub-method-macro.stderr
new file mode 100644
index 000000000..7c7a90926
--- /dev/null
+++ b/src/test/ui/parser/pub-method-macro.stderr
@@ -0,0 +1,10 @@
+error: can't qualify macro invocation with `pub`
+ --> $DIR/pub-method-macro.rs:17:9
+ |
+LL | pub defn!(f);
+ | ^^^ help: remove the visibility
+ |
+ = help: try adjusting the macro to put `pub` inside the invocation
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/public-instead-of-pub.fixed b/src/test/ui/parser/public-instead-of-pub.fixed
new file mode 100644
index 000000000..01db60999
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub.fixed
@@ -0,0 +1,8 @@
+// Checks what happens when `public` is used instead of the correct, `pub`
+// edition:2018
+// run-rustfix
+pub struct X;
+//~^ ERROR expected one of `!` or `::`, found keyword `struct`
+//~^^ HELP write `pub` instead of `public` to make the item public
+
+fn main() {}
diff --git a/src/test/ui/parser/public-instead-of-pub.rs b/src/test/ui/parser/public-instead-of-pub.rs
new file mode 100644
index 000000000..18e0fd3af
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub.rs
@@ -0,0 +1,8 @@
+// Checks what happens when `public` is used instead of the correct, `pub`
+// edition:2018
+// run-rustfix
+public struct X;
+//~^ ERROR expected one of `!` or `::`, found keyword `struct`
+//~^^ HELP write `pub` instead of `public` to make the item public
+
+fn main() {}
diff --git a/src/test/ui/parser/public-instead-of-pub.stderr b/src/test/ui/parser/public-instead-of-pub.stderr
new file mode 100644
index 000000000..af875491e
--- /dev/null
+++ b/src/test/ui/parser/public-instead-of-pub.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found keyword `struct`
+ --> $DIR/public-instead-of-pub.rs:4:8
+ |
+LL | public struct X;
+ | ^^^^^^ expected one of `!` or `::`
+ |
+help: write `pub` instead of `public` to make the item public
+ |
+LL | pub struct X;
+ | ~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/qualified-path-in-turbofish.fixed b/src/test/ui/parser/qualified-path-in-turbofish.fixed
new file mode 100644
index 000000000..404d2f776
--- /dev/null
+++ b/src/test/ui/parser/qualified-path-in-turbofish.fixed
@@ -0,0 +1,19 @@
+// run-rustfix
+trait T {
+ type Ty;
+}
+
+struct Impl;
+
+impl T for Impl {
+ type Ty = u32;
+}
+
+fn template<T>() -> i64 {
+ 3
+}
+
+fn main() {
+ template::<<Impl as T>::Ty>();
+ //~^ ERROR found single colon before projection in qualified path
+}
diff --git a/src/test/ui/parser/qualified-path-in-turbofish.rs b/src/test/ui/parser/qualified-path-in-turbofish.rs
new file mode 100644
index 000000000..2f4b2ed34
--- /dev/null
+++ b/src/test/ui/parser/qualified-path-in-turbofish.rs
@@ -0,0 +1,19 @@
+// run-rustfix
+trait T {
+ type Ty;
+}
+
+struct Impl;
+
+impl T for Impl {
+ type Ty = u32;
+}
+
+fn template<T>() -> i64 {
+ 3
+}
+
+fn main() {
+ template::<<Impl as T>:Ty>();
+ //~^ ERROR found single colon before projection in qualified path
+}
diff --git a/src/test/ui/parser/qualified-path-in-turbofish.stderr b/src/test/ui/parser/qualified-path-in-turbofish.stderr
new file mode 100644
index 000000000..8857d2ef3
--- /dev/null
+++ b/src/test/ui/parser/qualified-path-in-turbofish.stderr
@@ -0,0 +1,8 @@
+error: found single colon before projection in qualified path
+ --> $DIR/qualified-path-in-turbofish.rs:17:27
+ |
+LL | template::<<Impl as T>:Ty>();
+ | ^ help: use double colon: `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/range-3.rs b/src/test/ui/parser/range-3.rs
new file mode 100644
index 000000000..2c917a24e
--- /dev/null
+++ b/src/test/ui/parser/range-3.rs
@@ -0,0 +1,6 @@
+// Test range syntax - syntax errors.
+
+pub fn main() {
+ let r = 1..2..3;
+ //~^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `..`
+}
diff --git a/src/test/ui/parser/range-3.stderr b/src/test/ui/parser/range-3.stderr
new file mode 100644
index 000000000..340167f18
--- /dev/null
+++ b/src/test/ui/parser/range-3.stderr
@@ -0,0 +1,8 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `..`
+ --> $DIR/range-3.rs:4:17
+ |
+LL | let r = 1..2..3;
+ | ^^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/range-4.rs b/src/test/ui/parser/range-4.rs
new file mode 100644
index 000000000..c970c96de
--- /dev/null
+++ b/src/test/ui/parser/range-4.rs
@@ -0,0 +1,6 @@
+// Test range syntax - syntax errors.
+
+pub fn main() {
+ let r = ..1..2;
+ //~^ ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `..`
+}
diff --git a/src/test/ui/parser/range-4.stderr b/src/test/ui/parser/range-4.stderr
new file mode 100644
index 000000000..720d48938
--- /dev/null
+++ b/src/test/ui/parser/range-4.stderr
@@ -0,0 +1,8 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `..`
+ --> $DIR/range-4.rs:4:16
+ |
+LL | let r = ..1..2;
+ | ^^ expected one of `.`, `;`, `?`, `else`, or an operator
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/range-inclusive-extra-equals.rs b/src/test/ui/parser/range-inclusive-extra-equals.rs
new file mode 100644
index 000000000..d41c0699c
--- /dev/null
+++ b/src/test/ui/parser/range-inclusive-extra-equals.rs
@@ -0,0 +1,10 @@
+// Makes sure that a helpful message is shown when someone mistypes
+// an inclusive range as `..==` rather than `..=`. This is an
+// easy mistake, because of the resemblance to`==`.
+// See #86395 for a bit of background.
+
+pub fn main() {
+ if let 1..==3 = 1 {} //~ERROR unexpected `=` after inclusive range
+ //~|HELP use `..=` instead
+ //~|NOTE inclusive ranges end with a single equals sign
+}
diff --git a/src/test/ui/parser/range-inclusive-extra-equals.stderr b/src/test/ui/parser/range-inclusive-extra-equals.stderr
new file mode 100644
index 000000000..d37b6be4f
--- /dev/null
+++ b/src/test/ui/parser/range-inclusive-extra-equals.stderr
@@ -0,0 +1,10 @@
+error: unexpected `=` after inclusive range
+ --> $DIR/range-inclusive-extra-equals.rs:7:13
+ |
+LL | if let 1..==3 = 1 {}
+ | ^^^^ help: use `..=` instead
+ |
+ = note: inclusive ranges end with a single equals sign (`..=`)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/range_inclusive.fixed b/src/test/ui/parser/range_inclusive.fixed
new file mode 100644
index 000000000..fe23880d1
--- /dev/null
+++ b/src/test/ui/parser/range_inclusive.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+// Make sure that inclusive ranges with no end point don't parse.
+
+pub fn main() {
+ for _ in 1.. {} //~ERROR inclusive range with no end
+ //~^HELP use `..` instead
+}
diff --git a/src/test/ui/parser/range_inclusive.rs b/src/test/ui/parser/range_inclusive.rs
new file mode 100644
index 000000000..bc6d2413d
--- /dev/null
+++ b/src/test/ui/parser/range_inclusive.rs
@@ -0,0 +1,7 @@
+// run-rustfix
+// Make sure that inclusive ranges with no end point don't parse.
+
+pub fn main() {
+ for _ in 1..= {} //~ERROR inclusive range with no end
+ //~^HELP use `..` instead
+}
diff --git a/src/test/ui/parser/range_inclusive.stderr b/src/test/ui/parser/range_inclusive.stderr
new file mode 100644
index 000000000..8a9178263
--- /dev/null
+++ b/src/test/ui/parser/range_inclusive.stderr
@@ -0,0 +1,11 @@
+error[E0586]: inclusive range with no end
+ --> $DIR/range_inclusive.rs:5:15
+ |
+LL | for _ in 1..= {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/src/test/ui/parser/range_inclusive_dotdotdot.rs b/src/test/ui/parser/range_inclusive_dotdotdot.rs
new file mode 100644
index 000000000..c3e600e77
--- /dev/null
+++ b/src/test/ui/parser/range_inclusive_dotdotdot.rs
@@ -0,0 +1,23 @@
+// Make sure that inclusive ranges with `...` syntax don't parse.
+
+use std::ops::RangeToInclusive;
+
+fn return_range_to() -> RangeToInclusive<i32> {
+ return ...1; //~ERROR unexpected token: `...`
+ //~^HELP use `..` for an exclusive range
+ //~^^HELP or `..=` for an inclusive range
+}
+
+pub fn main() {
+ let x = ...0; //~ERROR unexpected token: `...`
+ //~^HELP use `..` for an exclusive range
+ //~^^HELP or `..=` for an inclusive range
+
+ let x = 5...5; //~ERROR unexpected token: `...`
+ //~^HELP use `..` for an exclusive range
+ //~^^HELP or `..=` for an inclusive range
+
+ for _ in 0...1 {} //~ERROR unexpected token: `...`
+ //~^HELP use `..` for an exclusive range
+ //~^^HELP or `..=` for an inclusive range
+}
diff --git a/src/test/ui/parser/range_inclusive_dotdotdot.stderr b/src/test/ui/parser/range_inclusive_dotdotdot.stderr
new file mode 100644
index 000000000..2dc2c87eb
--- /dev/null
+++ b/src/test/ui/parser/range_inclusive_dotdotdot.stderr
@@ -0,0 +1,62 @@
+error: unexpected token: `...`
+ --> $DIR/range_inclusive_dotdotdot.rs:6:12
+ |
+LL | return ...1;
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | return ..1;
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | return ..=1;
+ | ~~~
+
+error: unexpected token: `...`
+ --> $DIR/range_inclusive_dotdotdot.rs:12:13
+ |
+LL | let x = ...0;
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | let x = ..0;
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | let x = ..=0;
+ | ~~~
+
+error: unexpected token: `...`
+ --> $DIR/range_inclusive_dotdotdot.rs:16:14
+ |
+LL | let x = 5...5;
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | let x = 5..5;
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | let x = 5..=5;
+ | ~~~
+
+error: unexpected token: `...`
+ --> $DIR/range_inclusive_dotdotdot.rs:20:15
+ |
+LL | for _ in 0...1 {}
+ | ^^^
+ |
+help: use `..` for an exclusive range
+ |
+LL | for _ in 0..1 {}
+ | ~~
+help: or `..=` for an inclusive range
+ |
+LL | for _ in 0..=1 {}
+ | ~~~
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/ranges-precedence.rs b/src/test/ui/parser/ranges-precedence.rs
new file mode 100644
index 000000000..db241ed0c
--- /dev/null
+++ b/src/test/ui/parser/ranges-precedence.rs
@@ -0,0 +1,52 @@
+// run-pass
+// Test that the precedence of ranges is correct
+
+
+
+struct Foo {
+ foo: usize,
+}
+
+impl Foo {
+ fn bar(&self) -> usize { 5 }
+}
+
+fn main() {
+ let x = 1+3..4+5;
+ assert_eq!(x, (4..9));
+
+ let x = 1..4+5;
+ assert_eq!(x, (1..9));
+
+ let x = 1+3..4;
+ assert_eq!(x, (4..4));
+
+ let a = Foo { foo: 3 };
+ let x = a.foo..a.bar();
+ assert_eq!(x, (3..5));
+
+ let x = 1+3..;
+ assert_eq!(x, (4..));
+ let x = ..1+3;
+ assert_eq!(x, (..4));
+
+ let a = &[0, 1, 2, 3, 4, 5, 6];
+ let x = &a[1+1..2+2];
+ assert_eq!(x, &a[2..4]);
+ let x = &a[..1+2];
+ assert_eq!(x, &a[..3]);
+ let x = &a[1+2..];
+ assert_eq!(x, &a[3..]);
+
+ for _i in 2+4..10-3 {}
+
+ let i = 42;
+ for _ in 1..i {}
+ for _ in 1.. { break; }
+
+ let x = [1]..[2];
+ assert_eq!(x, (([1])..([2])));
+
+ let y = ..;
+ assert_eq!(y, (..));
+}
diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs
new file mode 100644
index 000000000..bdfc29a3d
--- /dev/null
+++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs
@@ -0,0 +1,5 @@
+// This won't actually panic because of the error comment -- the `"` needs to be
+// the last byte in the file (including not having a trailing newline)
+// Prior to the fix you get the error: 'expected item, found `r" ...`'
+// because the string being unterminated wasn't properly detected.
+r" //~ unterminated raw string
diff --git a/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr
new file mode 100644
index 000000000..3a7e2a4b1
--- /dev/null
+++ b/src/test/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.stderr
@@ -0,0 +1,9 @@
+error[E0748]: unterminated raw string
+ --> $DIR/issue-70677-panic-on-unterminated-raw-str-at-eof.rs:5:1
+ |
+LL | r"
+ | ^ unterminated raw string
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/raw/raw-byte-string-eof.rs b/src/test/ui/parser/raw/raw-byte-string-eof.rs
new file mode 100644
index 000000000..b74907b72
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-byte-string-eof.rs
@@ -0,0 +1,3 @@
+pub fn main() {
+ br##"a"#; //~ unterminated raw string
+}
diff --git a/src/test/ui/parser/raw/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr
new file mode 100644
index 000000000..a76668e80
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-byte-string-eof.stderr
@@ -0,0 +1,13 @@
+error[E0748]: unterminated raw string
+ --> $DIR/raw-byte-string-eof.rs:2:5
+ |
+LL | br##"a"#;
+ | ^ - help: consider terminating the string here: `##`
+ | |
+ | unterminated raw string
+ |
+ = note: this raw string should be terminated with `"##`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs
new file mode 100644
index 000000000..163c8ac66
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.rs
@@ -0,0 +1,7 @@
+// ignore-tidy-cr
+
+pub fn main() {
+ br"a "; //~ ERROR bare CR not allowed in raw string
+ br"é"; //~ ERROR raw byte string must be ASCII
+ br##~"a"~##; //~ ERROR only `#` is allowed in raw string delimitation
+}
diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
new file mode 100644
index 000000000..cfc877104
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
@@ -0,0 +1,20 @@
+error: bare CR not allowed in raw string
+ --> $DIR/raw-byte-string-literals.rs:4:9
+ |
+LL | br"a ";
+ | ^
+
+error: raw byte string must be ASCII
+ --> $DIR/raw-byte-string-literals.rs:5:8
+ |
+LL | br"é";
+ | ^ must be ASCII
+
+error: found invalid character; only `#` is allowed in raw string delimitation: ~
+ --> $DIR/raw-byte-string-literals.rs:6:5
+ |
+LL | br##~"a"~##;
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/raw/raw-literal-keywords.rs b/src/test/ui/parser/raw/raw-literal-keywords.rs
new file mode 100644
index 000000000..a986980fa
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-literal-keywords.rs
@@ -0,0 +1,25 @@
+fn test_if() {
+ r#if true { } //~ ERROR found keyword `true`
+}
+
+fn test_struct() {
+ r#struct Test; //~ ERROR found `Test`
+}
+
+fn test_union() {
+ r#union Test; //~ ERROR found `Test`
+}
+
+fn test_if_2() {
+ let _ = r#if; //~ ERROR cannot find value `r#if` in this scope
+}
+
+fn test_struct_2() {
+ let _ = r#struct; //~ ERROR cannot find value `r#struct` in this scope
+}
+
+fn test_union_2() {
+ let _ = r#union; //~ ERROR cannot find value `union` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/raw/raw-literal-keywords.stderr b/src/test/ui/parser/raw/raw-literal-keywords.stderr
new file mode 100644
index 000000000..f7b6c894a
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-literal-keywords.stderr
@@ -0,0 +1,39 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found keyword `true`
+ --> $DIR/raw-literal-keywords.rs:2:10
+ |
+LL | r#if true { }
+ | ^^^^ expected one of 8 possible tokens
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
+ --> $DIR/raw-literal-keywords.rs:6:14
+ |
+LL | r#struct Test;
+ | ^^^^ expected one of 8 possible tokens
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
+ --> $DIR/raw-literal-keywords.rs:10:13
+ |
+LL | r#union Test;
+ | ^^^^ expected one of 8 possible tokens
+
+error[E0425]: cannot find value `r#if` in this scope
+ --> $DIR/raw-literal-keywords.rs:14:13
+ |
+LL | let _ = r#if;
+ | ^^^^ not found in this scope
+
+error[E0425]: cannot find value `r#struct` in this scope
+ --> $DIR/raw-literal-keywords.rs:18:13
+ |
+LL | let _ = r#struct;
+ | ^^^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `union` in this scope
+ --> $DIR/raw-literal-keywords.rs:22:13
+ |
+LL | let _ = r#union;
+ | ^^^^^^^ not found in this scope
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/raw/raw-literal-self.rs b/src/test/ui/parser/raw/raw-literal-self.rs
new file mode 100644
index 000000000..a0c9e24c2
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-literal-self.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let r#self: ();
+ //~^ ERROR `self` cannot be a raw identifier
+}
diff --git a/src/test/ui/parser/raw/raw-literal-self.stderr b/src/test/ui/parser/raw/raw-literal-self.stderr
new file mode 100644
index 000000000..2a40dfe20
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-literal-self.stderr
@@ -0,0 +1,8 @@
+error: `self` cannot be a raw identifier
+ --> $DIR/raw-literal-self.rs:2:9
+ |
+LL | let r#self: ();
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/raw/raw-literal-underscore.rs b/src/test/ui/parser/raw/raw-literal-underscore.rs
new file mode 100644
index 000000000..a9d9e13a9
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-literal-underscore.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let r#_: ();
+ //~^ ERROR `_` cannot be a raw identifier
+}
diff --git a/src/test/ui/parser/raw/raw-literal-underscore.stderr b/src/test/ui/parser/raw/raw-literal-underscore.stderr
new file mode 100644
index 000000000..d7a364d85
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-literal-underscore.stderr
@@ -0,0 +1,8 @@
+error: `_` cannot be a raw identifier
+ --> $DIR/raw-literal-underscore.rs:2:9
+ |
+LL | let r#_: ();
+ | ^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/raw/raw-str-delim.rs b/src/test/ui/parser/raw/raw-str-delim.rs
new file mode 100644
index 000000000..2f13893ce
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-delim.rs
@@ -0,0 +1,3 @@
+static s: &'static str =
+ r#~"#"~# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation
+;
diff --git a/src/test/ui/parser/raw/raw-str-delim.stderr b/src/test/ui/parser/raw/raw-str-delim.stderr
new file mode 100644
index 000000000..8a04f99a1
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-delim.stderr
@@ -0,0 +1,8 @@
+error: found invalid character; only `#` is allowed in raw string delimitation: ~
+ --> $DIR/raw-str-delim.rs:2:5
+ |
+LL | r#~"#"~#
+ | ^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/raw/raw-str-in-macro-call.rs b/src/test/ui/parser/raw/raw-str-in-macro-call.rs
new file mode 100644
index 000000000..462c2279f
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-in-macro-call.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+macro_rules! m1 {
+ ($tt:tt #) => ()
+}
+
+macro_rules! m2 {
+ ($tt:tt) => ()
+}
+
+fn main() {
+ m1!(r#"abc"##);
+ m2!(r#"abc"#);
+}
diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs
new file mode 100644
index 000000000..38537f8b3
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unbalanced.rs
@@ -0,0 +1,22 @@
+static s: &'static str =
+ r#""## //~ ERROR too many `#` when terminating raw string
+;
+
+static s2: &'static str =
+ r#"
+ "#### //~ ERROR too many `#` when terminating raw string
+;
+
+const A: &'static str = r"" //~ ERROR expected `;`, found `#`
+
+// Test
+#[test]
+fn test() {}
+
+const B: &'static str = r""## //~ ERROR too many `#` when terminating raw string
+
+// Test
+#[test]
+fn test2() {}
+
+fn main() {}
diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr
new file mode 100644
index 000000000..eac8c06c1
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr
@@ -0,0 +1,36 @@
+error: too many `#` when terminating raw string
+ --> $DIR/raw-str-unbalanced.rs:2:10
+ |
+LL | r#""##
+ | -----^ help: remove the extra `#`
+ | |
+ | this raw string started with 1 `#`
+
+error: too many `#` when terminating raw string
+ --> $DIR/raw-str-unbalanced.rs:7:9
+ |
+LL | / r#"
+LL | | "####
+ | | -^^^ help: remove the extra `#`s
+ | |________|
+ | this raw string started with 1 `#`
+
+error: expected `;`, found `#`
+ --> $DIR/raw-str-unbalanced.rs:10:28
+ |
+LL | const A: &'static str = r""
+ | ^ help: add `;` here
+...
+LL | #[test]
+ | - unexpected token
+
+error: too many `#` when terminating raw string
+ --> $DIR/raw-str-unbalanced.rs:16:28
+ |
+LL | const B: &'static str = r""##
+ | ---^^ help: remove the extra `#`s
+ | |
+ | this raw string started with 0 `#`s
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/raw/raw-str-unterminated.rs b/src/test/ui/parser/raw/raw-str-unterminated.rs
new file mode 100644
index 000000000..fd3172955
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unterminated.rs
@@ -0,0 +1,4 @@
+static s: &'static str =
+ r#" string literal goes on
+ and on
+ //~^^ ERROR unterminated raw string
diff --git a/src/test/ui/parser/raw/raw-str-unterminated.stderr b/src/test/ui/parser/raw/raw-str-unterminated.stderr
new file mode 100644
index 000000000..077f763f1
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unterminated.stderr
@@ -0,0 +1,11 @@
+error[E0748]: unterminated raw string
+ --> $DIR/raw-str-unterminated.rs:2:5
+ |
+LL | r#" string literal goes on
+ | ^ unterminated raw string
+ |
+ = note: this raw string should be terminated with `"#`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/raw/raw-string-2.rs b/src/test/ui/parser/raw/raw-string-2.rs
new file mode 100644
index 000000000..067332d28
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string-2.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let x = r###"here's a long string"# "# "##;
+ //~^ ERROR unterminated raw string
+}
diff --git a/src/test/ui/parser/raw/raw-string-2.stderr b/src/test/ui/parser/raw/raw-string-2.stderr
new file mode 100644
index 000000000..8bbac9d7b
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string-2.stderr
@@ -0,0 +1,11 @@
+error[E0748]: unterminated raw string
+ --> $DIR/raw-string-2.rs:2:13
+ |
+LL | let x = r###"here's a long string"# "# "##;
+ | ^ unterminated raw string -- help: consider terminating the string here: `###`
+ |
+ = note: this raw string should be terminated with `"###`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/raw/raw-string.rs b/src/test/ui/parser/raw/raw-string.rs
new file mode 100644
index 000000000..84f07c4a9
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let x = r##"lol"#;
+ //~^ ERROR unterminated raw string
+}
diff --git a/src/test/ui/parser/raw/raw-string.stderr b/src/test/ui/parser/raw/raw-string.stderr
new file mode 100644
index 000000000..b2b853a89
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string.stderr
@@ -0,0 +1,13 @@
+error[E0748]: unterminated raw string
+ --> $DIR/raw-string.rs:2:13
+ |
+LL | let x = r##"lol"#;
+ | ^ - help: consider terminating the string here: `##`
+ | |
+ | unterminated raw string
+ |
+ = note: this raw string should be terminated with `"##`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/recover-assoc-const-constraint.rs b/src/test/ui/parser/recover-assoc-const-constraint.rs
new file mode 100644
index 000000000..1453e6cb5
--- /dev/null
+++ b/src/test/ui/parser/recover-assoc-const-constraint.rs
@@ -0,0 +1,9 @@
+#[cfg(FALSE)]
+fn syntax() {
+ bar::<Item = 42>();
+ //~^ ERROR associated const equality is incomplete
+ bar::<Item = { 42 }>();
+ //~^ ERROR associated const equality is incomplete
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-assoc-const-constraint.stderr b/src/test/ui/parser/recover-assoc-const-constraint.stderr
new file mode 100644
index 000000000..2d36ce4e9
--- /dev/null
+++ b/src/test/ui/parser/recover-assoc-const-constraint.stderr
@@ -0,0 +1,21 @@
+error[E0658]: associated const equality is incomplete
+ --> $DIR/recover-assoc-const-constraint.rs:3:11
+ |
+LL | bar::<Item = 42>();
+ | ^^^^^^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/recover-assoc-const-constraint.rs:5:11
+ |
+LL | bar::<Item = { 42 }>();
+ | ^^^^^^^^^^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/parser/recover-assoc-eq-missing-term.rs b/src/test/ui/parser/recover-assoc-eq-missing-term.rs
new file mode 100644
index 000000000..4b42c44dc
--- /dev/null
+++ b/src/test/ui/parser/recover-assoc-eq-missing-term.rs
@@ -0,0 +1,6 @@
+#[cfg(FALSE)]
+fn syntax() {
+ bar::<Item = >(); //~ ERROR missing type to the right of `=`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-assoc-eq-missing-term.stderr b/src/test/ui/parser/recover-assoc-eq-missing-term.stderr
new file mode 100644
index 000000000..152f7f2fb
--- /dev/null
+++ b/src/test/ui/parser/recover-assoc-eq-missing-term.stderr
@@ -0,0 +1,18 @@
+error: missing type to the right of `=`
+ --> $DIR/recover-assoc-eq-missing-term.rs:3:17
+ |
+LL | bar::<Item = >();
+ | ^^^
+ |
+help: to constrain the associated type, add a type after `=`
+ |
+LL | bar::<Item = TheType>();
+ | +++++++
+help: remove the `=` if `Item` is a type
+ |
+LL - bar::<Item = >();
+LL + bar::<Item >();
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-assoc-lifetime-constraint.rs b/src/test/ui/parser/recover-assoc-lifetime-constraint.rs
new file mode 100644
index 000000000..558fcdfe1
--- /dev/null
+++ b/src/test/ui/parser/recover-assoc-lifetime-constraint.rs
@@ -0,0 +1,6 @@
+#[cfg(FALSE)]
+fn syntax() {
+ bar::<Item = 'a>(); //~ ERROR associated lifetimes are not supported
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-assoc-lifetime-constraint.stderr b/src/test/ui/parser/recover-assoc-lifetime-constraint.stderr
new file mode 100644
index 000000000..79437533d
--- /dev/null
+++ b/src/test/ui/parser/recover-assoc-lifetime-constraint.stderr
@@ -0,0 +1,12 @@
+error: associated lifetimes are not supported
+ --> $DIR/recover-assoc-lifetime-constraint.rs:3:11
+ |
+LL | bar::<Item = 'a>();
+ | ^^^^^^^--
+ | |
+ | the lifetime is given here
+ |
+ = help: if you meant to specify a trait object, write `dyn Trait + 'lifetime`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-const-async-fn-ptr.rs b/src/test/ui/parser/recover-const-async-fn-ptr.rs
new file mode 100644
index 000000000..25af8772c
--- /dev/null
+++ b/src/test/ui/parser/recover-const-async-fn-ptr.rs
@@ -0,0 +1,25 @@
+// edition:2018
+
+type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T6 = const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+type FT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT5 = for<'a> async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT6 = for<'a> const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+fn main() {
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/recover-const-async-fn-ptr.stderr b/src/test/ui/parser/recover-const-async-fn-ptr.stderr
new file mode 100644
index 000000000..7012096b6
--- /dev/null
+++ b/src/test/ui/parser/recover-const-async-fn-ptr.stderr
@@ -0,0 +1,155 @@
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:3:11
+ |
+LL | type T0 = const fn();
+ | -----^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:4:11
+ |
+LL | type T1 = const extern "C" fn();
+ | -----^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:5:11
+ |
+LL | type T2 = const unsafe extern fn();
+ | -----^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:6:11
+ |
+LL | type T3 = async fn();
+ | -----^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:7:11
+ |
+LL | type T4 = async extern fn();
+ | -----^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:8:11
+ |
+LL | type T5 = async unsafe extern "C" fn();
+ | -----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:9:11
+ |
+LL | type T6 = const async unsafe extern "C" fn();
+ | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:9:11
+ |
+LL | type T6 = const async unsafe extern "C" fn();
+ | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:13:12
+ |
+LL | type FT0 = for<'a> const fn();
+ | ^^^^^^^^-----^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:14:12
+ |
+LL | type FT1 = for<'a> const extern "C" fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:15:12
+ |
+LL | type FT2 = for<'a> const unsafe extern fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:16:12
+ |
+LL | type FT3 = for<'a> async fn();
+ | ^^^^^^^^-----^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:17:12
+ |
+LL | type FT4 = for<'a> async extern fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:18:12
+ |
+LL | type FT5 = for<'a> async unsafe extern "C" fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+ --> $DIR/recover-const-async-fn-ptr.rs:19:12
+ |
+LL | type FT6 = for<'a> const async unsafe extern "C" fn();
+ | ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `const` because of this
+ | help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+ --> $DIR/recover-const-async-fn-ptr.rs:19:12
+ |
+LL | type FT6 = for<'a> const async unsafe extern "C" fn();
+ | ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | `async` because of this
+ | help: remove the `async` qualifier
+
+error[E0308]: mismatched types
+ --> $DIR/recover-const-async-fn-ptr.rs:24:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 17 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/recover-enum.rs b/src/test/ui/parser/recover-enum.rs
new file mode 100644
index 000000000..08dd939e2
--- /dev/null
+++ b/src/test/ui/parser/recover-enum.rs
@@ -0,0 +1,11 @@
+fn main() {
+ enum Test {
+ Very //~ HELP missing `,`
+ Bad(usize) //~ HELP missing `,`
+ //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
+ Stuff { a: usize } //~ HELP missing `,`
+ //~^ ERROR expected one of `,`, `=`, or `}`, found `Stuff`
+ Here
+ //~^ ERROR expected one of `,`, `=`, or `}`, found `Here`
+ }
+}
diff --git a/src/test/ui/parser/recover-enum.stderr b/src/test/ui/parser/recover-enum.stderr
new file mode 100644
index 000000000..a2b650e4f
--- /dev/null
+++ b/src/test/ui/parser/recover-enum.stderr
@@ -0,0 +1,37 @@
+error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
+ --> $DIR/recover-enum.rs:4:9
+ |
+LL | Very
+ | -
+ | |
+ | expected one of `(`, `,`, `=`, `{`, or `}`
+ | help: missing `,`
+LL | Bad(usize)
+ | ^^^ unexpected token
+
+error: expected one of `,`, `=`, or `}`, found `Stuff`
+ --> $DIR/recover-enum.rs:6:9
+ |
+LL | Bad(usize)
+ | -
+ | |
+ | expected one of `,`, `=`, or `}`
+ | help: missing `,`
+LL |
+LL | Stuff { a: usize }
+ | ^^^^^ unexpected token
+
+error: expected one of `,`, `=`, or `}`, found `Here`
+ --> $DIR/recover-enum.rs:8:9
+ |
+LL | Stuff { a: usize }
+ | -
+ | |
+ | expected one of `,`, `=`, or `}`
+ | help: missing `,`
+LL |
+LL | Here
+ | ^^^^ unexpected token
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/recover-enum2.rs b/src/test/ui/parser/recover-enum2.rs
new file mode 100644
index 000000000..0c9420889
--- /dev/null
+++ b/src/test/ui/parser/recover-enum2.rs
@@ -0,0 +1,28 @@
+fn main() {
+ enum Test {
+ Var1,
+ Var2(String),
+ Var3 {
+ abc: {}, //~ ERROR: expected type, found `{`
+ },
+ }
+
+ // recover...
+ let a = 1;
+ enum Test2 {
+ Fine,
+ }
+
+ enum Test3 {
+ StillFine {
+ def: i32,
+ },
+ }
+
+ {
+ // fail again
+ enum Test4 {
+ Nope(i32 {}) //~ ERROR: found `{`
+ }
+ }
+}
diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr
new file mode 100644
index 000000000..ee29f0663
--- /dev/null
+++ b/src/test/ui/parser/recover-enum2.stderr
@@ -0,0 +1,14 @@
+error: expected type, found `{`
+ --> $DIR/recover-enum2.rs:6:18
+ |
+LL | abc: {},
+ | ^ expected type
+
+error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
+ --> $DIR/recover-enum2.rs:25:22
+ |
+LL | Nope(i32 {})
+ | ^ expected one of 7 possible tokens
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs
new file mode 100644
index 000000000..e815c7611
--- /dev/null
+++ b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.rs
@@ -0,0 +1,6 @@
+struct TypedArenaChunk {
+ next: Option<String>>
+ //~^ ERROR unmatched angle bracket
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr
new file mode 100644
index 000000000..17237c930
--- /dev/null
+++ b/src/test/ui/parser/recover-field-extra-angle-brackets-in-struct-with-a-field.stderr
@@ -0,0 +1,11 @@
+error: unmatched angle bracket
+ --> $DIR/recover-field-extra-angle-brackets-in-struct-with-a-field.rs:2:25
+ |
+LL | next: Option<String>>
+ | _________________________^
+LL | |
+LL | | }
+ | |_ help: remove extra angle bracket
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets.rs b/src/test/ui/parser/recover-field-extra-angle-brackets.rs
new file mode 100644
index 000000000..5e0e00bcb
--- /dev/null
+++ b/src/test/ui/parser/recover-field-extra-angle-brackets.rs
@@ -0,0 +1,14 @@
+// Tests that we recover from extra trailing angle brackets
+// in a struct field
+
+struct BadStruct {
+ first: Vec<u8>>, //~ ERROR unmatched angle bracket
+ second: bool
+}
+
+fn bar(val: BadStruct) {
+ val.first;
+ val.second;
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/recover-field-extra-angle-brackets.stderr b/src/test/ui/parser/recover-field-extra-angle-brackets.stderr
new file mode 100644
index 000000000..318e55f6e
--- /dev/null
+++ b/src/test/ui/parser/recover-field-extra-angle-brackets.stderr
@@ -0,0 +1,8 @@
+error: unmatched angle bracket
+ --> $DIR/recover-field-extra-angle-brackets.rs:5:19
+ |
+LL | first: Vec<u8>>,
+ | ^ help: remove extra angle bracket
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.rs b/src/test/ui/parser/recover-for-loop-parens-around-head.rs
new file mode 100644
index 000000000..053b428bd
--- /dev/null
+++ b/src/test/ui/parser/recover-for-loop-parens-around-head.rs
@@ -0,0 +1,15 @@
+// Here we test that the parser is able to recover in a situation like
+// `for ( $pat in $expr )` since that is familiar syntax in other languages.
+// Instead we suggest that the user writes `for $pat in $expr`.
+
+#![deny(unused)] // Make sure we don't trigger `unused_parens`.
+
+fn main() {
+ let vec = vec![1, 2, 3];
+
+ for ( elem in vec ) {
+ //~^ ERROR expected one of `)`, `,`, `@`, or `|`, found keyword `in`
+ //~| ERROR unexpected parentheses surrounding `for` loop head
+ const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
+ }
+}
diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
new file mode 100644
index 000000000..3bad29f20
--- /dev/null
+++ b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
@@ -0,0 +1,27 @@
+error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
+ --> $DIR/recover-for-loop-parens-around-head.rs:10:16
+ |
+LL | for ( elem in vec ) {
+ | ^^ expected one of `)`, `,`, `@`, or `|`
+
+error: unexpected parentheses surrounding `for` loop head
+ --> $DIR/recover-for-loop-parens-around-head.rs:10:9
+ |
+LL | for ( elem in vec ) {
+ | ^ ^
+ |
+help: remove parentheses in `for` loop
+ |
+LL - for ( elem in vec ) {
+LL + for elem in vec {
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/recover-for-loop-parens-around-head.rs:13:38
+ |
+LL | const RECOVERY_WITNESS: () = 0;
+ | ^ expected `()`, found integer
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/recover-from-bad-variant.rs b/src/test/ui/parser/recover-from-bad-variant.rs
new file mode 100644
index 000000000..e8887147c
--- /dev/null
+++ b/src/test/ui/parser/recover-from-bad-variant.rs
@@ -0,0 +1,15 @@
+enum Enum {
+ Foo { a: usize, b: usize },
+ Bar(usize, usize),
+}
+
+fn main() {
+ let x = Enum::Foo(a: 3, b: 4);
+ //~^ ERROR invalid `struct` delimiters or `fn` call arguments
+ match x {
+ Enum::Foo(a, b) => {}
+ //~^ ERROR expected tuple struct or tuple variant, found struct variant `Enum::Foo`
+ Enum::Bar { a, b } => {}
+ //~^ ERROR tuple variant `Enum::Bar` written as struct variant
+ }
+}
diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr
new file mode 100644
index 000000000..483312c16
--- /dev/null
+++ b/src/test/ui/parser/recover-from-bad-variant.stderr
@@ -0,0 +1,40 @@
+error: invalid `struct` delimiters or `fn` call arguments
+ --> $DIR/recover-from-bad-variant.rs:7:13
+ |
+LL | let x = Enum::Foo(a: 3, b: 4);
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: if `Enum::Foo` is a struct, use braces as delimiters
+ |
+LL | let x = Enum::Foo { a: 3, b: 4 };
+ | ~ ~
+help: if `Enum::Foo` is a function, use the arguments directly
+ |
+LL - let x = Enum::Foo(a: 3, b: 4);
+LL + let x = Enum::Foo(3, 4);
+ |
+
+error[E0532]: expected tuple struct or tuple variant, found struct variant `Enum::Foo`
+ --> $DIR/recover-from-bad-variant.rs:10:9
+ |
+LL | Foo { a: usize, b: usize },
+ | -------------------------- `Enum::Foo` defined here
+...
+LL | Enum::Foo(a, b) => {}
+ | ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }`
+
+error[E0769]: tuple variant `Enum::Bar` written as struct variant
+ --> $DIR/recover-from-bad-variant.rs:12:9
+ |
+LL | Enum::Bar { a, b } => {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: use the tuple variant pattern syntax instead
+ |
+LL | Enum::Bar(a, b) => {}
+ | ~~~~~~
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0532, E0769.
+For more information about an error, try `rustc --explain E0532`.
diff --git a/src/test/ui/parser/recover-from-homoglyph.rs b/src/test/ui/parser/recover-from-homoglyph.rs
new file mode 100644
index 000000000..99ce0d1a6
--- /dev/null
+++ b/src/test/ui/parser/recover-from-homoglyph.rs
@@ -0,0 +1,4 @@
+fn main() {
+ println!(""); //~ ERROR unknown start of token: \u{37e}
+ let x: usize = (); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/recover-from-homoglyph.stderr b/src/test/ui/parser/recover-from-homoglyph.stderr
new file mode 100644
index 000000000..f11ca9fd5
--- /dev/null
+++ b/src/test/ui/parser/recover-from-homoglyph.stderr
@@ -0,0 +1,22 @@
+error: unknown start of token: \u{37e}
+ --> $DIR/recover-from-homoglyph.rs:2:17
+ |
+LL | println!("");
+ | ^
+ |
+help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
+ |
+LL | println!("");
+ | ~
+
+error[E0308]: mismatched types
+ --> $DIR/recover-from-homoglyph.rs:3:20
+ |
+LL | let x: usize = ();
+ | ----- ^^ expected `usize`, found `()`
+ | |
+ | expected due to this
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.fixed b/src/test/ui/parser/recover-labeled-non-block-expr.fixed
new file mode 100644
index 000000000..fe546a719
--- /dev/null
+++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed
@@ -0,0 +1,27 @@
+// run-rustfix
+#![feature(label_break_value)]
+fn main() {
+ let _ = 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+
+ match () { () => {}, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+ 'label: { match () { () => break 'label, } }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+ #[allow(unused_labels)]
+ 'label: { match () { () => 'lp: loop { break 'lp 0 }, } }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+
+ let x = 1;
+ let _i = 'label: { match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+ 0 => 42,
+ 1 if false => break 'label 17,
+ 1 => {
+ if true {
+ break 'label 13
+ } else {
+ break 'label 0;
+ }
+ }
+ _ => 1,
+ } };
+
+ let other = 3;
+ let _val = 'label: { (1, if other == 3 { break 'label (2, 3) } else { other }) }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+}
diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.rs b/src/test/ui/parser/recover-labeled-non-block-expr.rs
new file mode 100644
index 000000000..35862e2ee
--- /dev/null
+++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs
@@ -0,0 +1,27 @@
+// run-rustfix
+#![feature(label_break_value)]
+fn main() {
+ let _ = 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+
+ 'label: match () { () => {}, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+ 'label: match () { () => break 'label, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+ #[allow(unused_labels)]
+ 'label: match () { () => 'lp: loop { break 'lp 0 }, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+
+ let x = 1;
+ let _i = 'label: match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+ 0 => 42,
+ 1 if false => break 'label 17,
+ 1 => {
+ if true {
+ break 'label 13
+ } else {
+ break 'label 0;
+ }
+ }
+ _ => 1,
+ };
+
+ let other = 3;
+ let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); //~ ERROR expected `while`, `for`, `loop` or `{` after a label
+}
diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.stderr b/src/test/ui/parser/recover-labeled-non-block-expr.stderr
new file mode 100644
index 000000000..04fc1203e
--- /dev/null
+++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr
@@ -0,0 +1,74 @@
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/recover-labeled-non-block-expr.rs:4:21
+ |
+LL | let _ = 'label: 1 + 1;
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider removing the label
+ |
+LL - let _ = 'label: 1 + 1;
+LL + let _ = 1 + 1;
+ |
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/recover-labeled-non-block-expr.rs:6:13
+ |
+LL | 'label: match () { () => {}, };
+ | ^^^^^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider removing the label
+ |
+LL - 'label: match () { () => {}, };
+LL + match () { () => {}, };
+ |
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/recover-labeled-non-block-expr.rs:7:13
+ |
+LL | 'label: match () { () => break 'label, };
+ | ^^^^^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider enclosing expression in a block
+ |
+LL | 'label: { match () { () => break 'label, } };
+ | + +
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/recover-labeled-non-block-expr.rs:9:13
+ |
+LL | 'label: match () { () => 'lp: loop { break 'lp 0 }, };
+ | ^^^^^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider enclosing expression in a block
+ |
+LL | 'label: { match () { () => 'lp: loop { break 'lp 0 }, } };
+ | + +
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/recover-labeled-non-block-expr.rs:12:22
+ |
+LL | let _i = 'label: match x {
+ | ^^^^^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider enclosing expression in a block
+ |
+LL ~ let _i = 'label: { match x {
+LL | 0 => 42,
+ ...
+LL | _ => 1,
+LL ~ } };
+ |
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/recover-labeled-non-block-expr.rs:26:24
+ |
+LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other });
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+ |
+help: consider enclosing expression in a block
+ |
+LL | let _val = 'label: { (1, if other == 3 { break 'label (2, 3) } else { other }) };
+ | + +
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/recover-missing-semi.rs b/src/test/ui/parser/recover-missing-semi.rs
new file mode 100644
index 000000000..f47d5e680
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi.rs
@@ -0,0 +1,13 @@
+fn main() {
+ let _: usize = ()
+ //~^ ERROR mismatched types
+ //~| ERROR expected `;`
+ let _ = 3;
+}
+
+fn foo() -> usize {
+ let _: usize = ()
+ //~^ ERROR mismatched types
+ //~| ERROR expected `;`
+ return 3;
+}
diff --git a/src/test/ui/parser/recover-missing-semi.stderr b/src/test/ui/parser/recover-missing-semi.stderr
new file mode 100644
index 000000000..ba4798285
--- /dev/null
+++ b/src/test/ui/parser/recover-missing-semi.stderr
@@ -0,0 +1,37 @@
+error: expected `;`, found keyword `let`
+ --> $DIR/recover-missing-semi.rs:2:22
+ |
+LL | let _: usize = ()
+ | ^ help: add `;` here
+...
+LL | let _ = 3;
+ | --- unexpected token
+
+error: expected `;`, found keyword `return`
+ --> $DIR/recover-missing-semi.rs:9:22
+ |
+LL | let _: usize = ()
+ | ^ help: add `;` here
+...
+LL | return 3;
+ | ------ unexpected token
+
+error[E0308]: mismatched types
+ --> $DIR/recover-missing-semi.rs:2:20
+ |
+LL | let _: usize = ()
+ | ----- ^^ expected `usize`, found `()`
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/recover-missing-semi.rs:9:20
+ |
+LL | let _: usize = ()
+ | ----- ^^ expected `usize`, found `()`
+ | |
+ | expected due to this
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/recover-quantified-closure.rs b/src/test/ui/parser/recover-quantified-closure.rs
new file mode 100644
index 000000000..10af39b70
--- /dev/null
+++ b/src/test/ui/parser/recover-quantified-closure.rs
@@ -0,0 +1,12 @@
+fn main() {
+ for<'a> |x: &'a u8| *x + 1;
+ //~^ ERROR `for<...>` binders for closures are experimental
+ //~^^ ERROR implicit types in closure signatures are forbidden when `for<...>` is present
+}
+
+enum Foo { Bar }
+fn foo(x: impl Iterator<Item = Foo>) {
+ for <Foo>::Bar in x {}
+ //~^ ERROR expected one of `move`, `static`, `|`
+ //~^^ ERROR `for<...>` binders for closures are experimental
+}
diff --git a/src/test/ui/parser/recover-quantified-closure.stderr b/src/test/ui/parser/recover-quantified-closure.stderr
new file mode 100644
index 000000000..39eec80f6
--- /dev/null
+++ b/src/test/ui/parser/recover-quantified-closure.stderr
@@ -0,0 +1,37 @@
+error: expected one of `move`, `static`, `|`, or `||`, found `::`
+ --> $DIR/recover-quantified-closure.rs:9:14
+ |
+LL | for <Foo>::Bar in x {}
+ | ^^ expected one of `move`, `static`, `|`, or `||`
+
+error[E0658]: `for<...>` binders for closures are experimental
+ --> $DIR/recover-quantified-closure.rs:2:5
+ |
+LL | for<'a> |x: &'a u8| *x + 1;
+ | ^^^^^^^
+ |
+ = note: see issue #97362 <https://github.com/rust-lang/rust/issues/97362> for more information
+ = help: add `#![feature(closure_lifetime_binder)]` to the crate attributes to enable
+ = help: consider removing `for<...>`
+
+error[E0658]: `for<...>` binders for closures are experimental
+ --> $DIR/recover-quantified-closure.rs:9:5
+ |
+LL | for <Foo>::Bar in x {}
+ | ^^^^^^^^^
+ |
+ = note: see issue #97362 <https://github.com/rust-lang/rust/issues/97362> for more information
+ = help: add `#![feature(closure_lifetime_binder)]` to the crate attributes to enable
+ = help: consider removing `for<...>`
+
+error: implicit types in closure signatures are forbidden when `for<...>` is present
+ --> $DIR/recover-quantified-closure.rs:2:25
+ |
+LL | for<'a> |x: &'a u8| *x + 1;
+ | ------- ^
+ | |
+ | `for<...>` is here
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs
new file mode 100644
index 000000000..2e5a99154
--- /dev/null
+++ b/src/test/ui/parser/recover-range-pats.rs
@@ -0,0 +1,160 @@
+// Here we test all kinds of range patterns in terms of parsing / recovery.
+// We want to ensure that:
+// 1. Things parse as they should.
+// 2. Or at least we have parser recovery if they don't.
+
+#![feature(exclusive_range_pattern)]
+#![feature(half_open_range_patterns)]
+#![deny(ellipsis_inclusive_range_patterns)]
+
+fn main() {}
+
+const X: u8 = 0;
+const Y: u8 = 3;
+
+fn exclusive_from_to() {
+ if let 0..3 = 0 {} // OK.
+ if let 0..Y = 0 {} // OK.
+ if let X..3 = 0 {} // OK.
+ if let X..Y = 0 {} // OK.
+ if let true..Y = 0 {} //~ ERROR only `char` and numeric types
+ if let X..true = 0 {} //~ ERROR only `char` and numeric types
+ if let .0..Y = 0 {} //~ ERROR mismatched types
+ //~^ ERROR float literals must have an integer part
+ if let X.. .0 = 0 {} //~ ERROR mismatched types
+ //~^ ERROR float literals must have an integer part
+}
+
+fn inclusive_from_to() {
+ if let 0..=3 = 0 {} // OK.
+ if let 0..=Y = 0 {} // OK.
+ if let X..=3 = 0 {} // OK.
+ if let X..=Y = 0 {} // OK.
+ if let true..=Y = 0 {} //~ ERROR only `char` and numeric types
+ if let X..=true = 0 {} //~ ERROR only `char` and numeric types
+ if let .0..=Y = 0 {} //~ ERROR mismatched types
+ //~^ ERROR float literals must have an integer part
+ if let X..=.0 = 0 {} //~ ERROR mismatched types
+ //~^ ERROR float literals must have an integer part
+}
+
+fn inclusive2_from_to() {
+ if let 0...3 = 0 {}
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ if let 0...Y = 0 {}
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ if let X...3 = 0 {}
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ if let X...Y = 0 {}
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ if let true...Y = 0 {} //~ ERROR only `char` and numeric types
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ if let X...true = 0 {} //~ ERROR only `char` and numeric types
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ if let .0...Y = 0 {} //~ ERROR mismatched types
+ //~^ ERROR float literals must have an integer part
+ //~| WARN this is accepted in the current edition
+ //~| ERROR `...` range patterns are deprecated
+ if let X... .0 = 0 {} //~ ERROR mismatched types
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+}
+
+fn exclusive_from() {
+ if let 0.. = 0 {}
+ if let X.. = 0 {}
+ if let true.. = 0 {}
+ //~^ ERROR only `char` and numeric types
+ if let .0.. = 0 {}
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR mismatched types
+}
+
+fn inclusive_from() {
+ if let 0..= = 0 {} //~ ERROR inclusive range with no end
+ if let X..= = 0 {} //~ ERROR inclusive range with no end
+ if let true..= = 0 {} //~ ERROR inclusive range with no end
+ //~| ERROR only `char` and numeric types
+ if let .0..= = 0 {} //~ ERROR inclusive range with no end
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR mismatched types
+}
+
+fn inclusive2_from() {
+ if let 0... = 0 {} //~ ERROR inclusive range with no end
+ if let X... = 0 {} //~ ERROR inclusive range with no end
+ if let true... = 0 {} //~ ERROR inclusive range with no end
+ //~| ERROR only `char` and numeric types
+ if let .0... = 0 {} //~ ERROR inclusive range with no end
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR mismatched types
+}
+
+fn exclusive_to() {
+ if let ..0 = 0 {}
+ if let ..Y = 0 {}
+ if let ..true = 0 {}
+ //~^ ERROR only `char` and numeric types
+ if let .. .0 = 0 {}
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR mismatched types
+}
+
+fn inclusive_to() {
+ if let ..=3 = 0 {}
+ if let ..=Y = 0 {}
+ if let ..=true = 0 {}
+ //~^ ERROR only `char` and numeric types
+ if let ..=.0 = 0 {}
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR mismatched types
+}
+
+fn inclusive2_to() {
+ if let ...3 = 0 {}
+ //~^ ERROR range-to patterns with `...` are not allowed
+ if let ...Y = 0 {}
+ //~^ ERROR range-to patterns with `...` are not allowed
+ if let ...true = 0 {}
+ //~^ ERROR range-to patterns with `...` are not allowed
+ //~| ERROR only `char` and numeric types
+ if let ....3 = 0 {}
+ //~^ ERROR float literals must have an integer part
+ //~| ERROR range-to patterns with `...` are not allowed
+ //~| ERROR mismatched types
+}
+
+fn with_macro_expr_var() {
+ macro_rules! mac2 {
+ ($e1:expr, $e2:expr) => {
+ let $e1..$e2;
+ let $e1...$e2;
+ //~^ ERROR `...` range patterns are deprecated
+ //~| WARN this is accepted in the current edition
+ let $e1..=$e2;
+ }
+ }
+
+ mac2!(0, 1);
+
+ macro_rules! mac {
+ ($e:expr) => {
+ let ..$e;
+ let ...$e;
+ //~^ ERROR range-to patterns with `...` are not allowed
+ let ..=$e;
+ let $e..;
+ let $e...; //~ ERROR inclusive range with no end
+ let $e..=; //~ ERROR inclusive range with no end
+ }
+ }
+
+ mac!(0);
+}
diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr
new file mode 100644
index 000000000..d0979b23f
--- /dev/null
+++ b/src/test/ui/parser/recover-range-pats.stderr
@@ -0,0 +1,484 @@
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:22:12
+ |
+LL | if let .0..Y = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:24:16
+ |
+LL | if let X.. .0 = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:35:12
+ |
+LL | if let .0..=Y = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:37:16
+ |
+LL | if let X..=.0 = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:60:12
+ |
+LL | if let .0...Y = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:64:17
+ |
+LL | if let X... .0 = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:75:12
+ |
+LL | if let .0.. = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:81:13
+ |
+LL | if let 0..= = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:82:13
+ |
+LL | if let X..= = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:83:16
+ |
+LL | if let true..= = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:85:12
+ |
+LL | if let .0..= = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:85:14
+ |
+LL | if let .0..= = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:91:13
+ |
+LL | if let 0... = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:92:13
+ |
+LL | if let X... = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:93:16
+ |
+LL | if let true... = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:95:12
+ |
+LL | if let .0... = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:95:14
+ |
+LL | if let .0... = 0 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:105:15
+ |
+LL | if let .. .0 = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:115:15
+ |
+LL | if let ..=.0 = 0 {}
+ | ^^ help: must have an integer part: `0.0`
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/recover-range-pats.rs:121:12
+ |
+LL | if let ...3 = 0 {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/recover-range-pats.rs:123:12
+ |
+LL | if let ...Y = 0 {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/recover-range-pats.rs:125:12
+ |
+LL | if let ...true = 0 {}
+ | ^^^ help: use `..=` instead
+
+error: float literals must have an integer part
+ --> $DIR/recover-range-pats.rs:128:15
+ |
+LL | if let ....3 = 0 {}
+ | ^^ help: must have an integer part: `0.3`
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/recover-range-pats.rs:128:12
+ |
+LL | if let ....3 = 0 {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/recover-range-pats.rs:150:17
+ |
+LL | let ...$e;
+ | ^^^ help: use `..=` instead
+...
+LL | mac!(0);
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:154:19
+ |
+LL | let $e...;
+ | ^^^ help: use `..` instead
+...
+LL | mac!(0);
+ | ------- in this macro invocation
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/recover-range-pats.rs:155:19
+ |
+LL | let $e..=;
+ | ^^^ help: use `..` instead
+...
+LL | mac!(0);
+ | ------- in this macro invocation
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:42:13
+ |
+LL | if let 0...3 = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+note: the lint level is defined here
+ --> $DIR/recover-range-pats.rs:8:9
+ |
+LL | #![deny(ellipsis_inclusive_range_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:45:13
+ |
+LL | if let 0...Y = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:48:13
+ |
+LL | if let X...3 = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:51:13
+ |
+LL | if let X...Y = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:54:16
+ |
+LL | if let true...Y = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:57:13
+ |
+LL | if let X...true = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:60:14
+ |
+LL | if let .0...Y = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:64:13
+ |
+LL | if let X... .0 = 0 {}
+ | ^^^ help: use `..=` for an inclusive range
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: `...` range patterns are deprecated
+ --> $DIR/recover-range-pats.rs:138:20
+ |
+LL | let $e1...$e2;
+ | ^^^ help: use `..=` for an inclusive range
+...
+LL | mac2!(0, 1);
+ | ----------- in this macro invocation
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:20:12
+ |
+LL | if let true..Y = 0 {}
+ | ^^^^ - this is of type `u8`
+ | |
+ | this is of type `bool` but it should be `char` or numeric
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:21:15
+ |
+LL | if let X..true = 0 {}
+ | - ^^^^ this is of type `bool` but it should be `char` or numeric
+ | |
+ | this is of type `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:22:12
+ |
+LL | if let .0..Y = 0 {}
+ | ^^ - - this expression has type `{integer}`
+ | | |
+ | | this is of type `u8`
+ | expected integer, found floating-point number
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:24:16
+ |
+LL | if let X.. .0 = 0 {}
+ | - ^^ - this expression has type `u8`
+ | | |
+ | | expected integer, found floating-point number
+ | this is of type `u8`
+ |
+ = note: expected type `u8`
+ found type `{float}`
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:33:12
+ |
+LL | if let true..=Y = 0 {}
+ | ^^^^ - this is of type `u8`
+ | |
+ | this is of type `bool` but it should be `char` or numeric
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:34:16
+ |
+LL | if let X..=true = 0 {}
+ | - ^^^^ this is of type `bool` but it should be `char` or numeric
+ | |
+ | this is of type `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:35:12
+ |
+LL | if let .0..=Y = 0 {}
+ | ^^ - - this expression has type `{integer}`
+ | | |
+ | | this is of type `u8`
+ | expected integer, found floating-point number
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:37:16
+ |
+LL | if let X..=.0 = 0 {}
+ | - ^^ - this expression has type `u8`
+ | | |
+ | | expected integer, found floating-point number
+ | this is of type `u8`
+ |
+ = note: expected type `u8`
+ found type `{float}`
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:54:12
+ |
+LL | if let true...Y = 0 {}
+ | ^^^^ - this is of type `u8`
+ | |
+ | this is of type `bool` but it should be `char` or numeric
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:57:16
+ |
+LL | if let X...true = 0 {}
+ | - ^^^^ this is of type `bool` but it should be `char` or numeric
+ | |
+ | this is of type `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:60:12
+ |
+LL | if let .0...Y = 0 {}
+ | ^^ - - this expression has type `{integer}`
+ | | |
+ | | this is of type `u8`
+ | expected integer, found floating-point number
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:64:17
+ |
+LL | if let X... .0 = 0 {}
+ | - ^^ - this expression has type `u8`
+ | | |
+ | | expected integer, found floating-point number
+ | this is of type `u8`
+ |
+ = note: expected type `u8`
+ found type `{float}`
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:73:12
+ |
+LL | if let true.. = 0 {}
+ | ^^^^ this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:75:12
+ |
+LL | if let .0.. = 0 {}
+ | ^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:83:12
+ |
+LL | if let true..= = 0 {}
+ | ^^^^ this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:85:12
+ |
+LL | if let .0..= = 0 {}
+ | ^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:93:12
+ |
+LL | if let true... = 0 {}
+ | ^^^^ this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:95:12
+ |
+LL | if let .0... = 0 {}
+ | ^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:103:14
+ |
+LL | if let ..true = 0 {}
+ | ^^^^ this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:105:15
+ |
+LL | if let .. .0 = 0 {}
+ | ^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:113:15
+ |
+LL | if let ..=true = 0 {}
+ | ^^^^ this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:115:15
+ |
+LL | if let ..=.0 = 0 {}
+ | ^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/recover-range-pats.rs:125:15
+ |
+LL | if let ...true = 0 {}
+ | ^^^^ this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/recover-range-pats.rs:128:15
+ |
+LL | if let ....3 = 0 {}
+ | ^^ - this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error: aborting due to 60 previous errors
+
+Some errors have detailed explanations: E0029, E0308, E0586.
+For more information about an error, try `rustc --explain E0029`.
diff --git a/src/test/ui/parser/recover-ref-dyn-mut.rs b/src/test/ui/parser/recover-ref-dyn-mut.rs
new file mode 100644
index 000000000..3016275cc
--- /dev/null
+++ b/src/test/ui/parser/recover-ref-dyn-mut.rs
@@ -0,0 +1,9 @@
+// Test that the parser detects `&dyn mut`, offers a help message, and
+// recovers.
+
+fn main() {
+ let r: &dyn mut Trait;
+ //~^ ERROR: `mut` must precede `dyn`
+ //~| HELP: place `mut` before `dyn`
+ //~| ERROR: cannot find trait `Trait` in this scope [E0405]
+}
diff --git a/src/test/ui/parser/recover-ref-dyn-mut.stderr b/src/test/ui/parser/recover-ref-dyn-mut.stderr
new file mode 100644
index 000000000..c048c8ea1
--- /dev/null
+++ b/src/test/ui/parser/recover-ref-dyn-mut.stderr
@@ -0,0 +1,15 @@
+error: `mut` must precede `dyn`
+ --> $DIR/recover-ref-dyn-mut.rs:5:12
+ |
+LL | let r: &dyn mut Trait;
+ | ^^^^^^^^ help: place `mut` before `dyn`: `&mut dyn`
+
+error[E0405]: cannot find trait `Trait` in this scope
+ --> $DIR/recover-ref-dyn-mut.rs:5:21
+ |
+LL | let r: &dyn mut Trait;
+ | ^^^^^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/src/test/ui/parser/recover-struct.rs b/src/test/ui/parser/recover-struct.rs
new file mode 100644
index 000000000..bfa5b454c
--- /dev/null
+++ b/src/test/ui/parser/recover-struct.rs
@@ -0,0 +1,7 @@
+fn main() {
+ struct Test {
+ Very
+ Bad //~ ERROR found `Bad`
+ Stuff
+ }
+}
diff --git a/src/test/ui/parser/recover-struct.stderr b/src/test/ui/parser/recover-struct.stderr
new file mode 100644
index 000000000..1b72184b0
--- /dev/null
+++ b/src/test/ui/parser/recover-struct.stderr
@@ -0,0 +1,10 @@
+error: expected `:`, found `Bad`
+ --> $DIR/recover-struct.rs:4:9
+ |
+LL | Very
+ | - expected `:`
+LL | Bad
+ | ^^^ unexpected token
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-tuple-pat.rs b/src/test/ui/parser/recover-tuple-pat.rs
new file mode 100644
index 000000000..7fded752d
--- /dev/null
+++ b/src/test/ui/parser/recover-tuple-pat.rs
@@ -0,0 +1,12 @@
+// NOTE: This doesn't recover anymore.
+
+fn main() {
+ let x = (1, 2, 3, 4);
+ match x {
+ (1, .., 4) => {}
+ (1, .=., 4) => { let _: usize = ""; }
+ //~^ ERROR expected pattern, found `.`
+ (.=., 4) => {}
+ (1, 2, 3, 4) => {}
+ }
+}
diff --git a/src/test/ui/parser/recover-tuple-pat.stderr b/src/test/ui/parser/recover-tuple-pat.stderr
new file mode 100644
index 000000000..93a6a66a6
--- /dev/null
+++ b/src/test/ui/parser/recover-tuple-pat.stderr
@@ -0,0 +1,8 @@
+error: expected pattern, found `.`
+ --> $DIR/recover-tuple-pat.rs:7:13
+ |
+LL | (1, .=., 4) => { let _: usize = ""; }
+ | ^ expected pattern
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/recover-tuple.rs b/src/test/ui/parser/recover-tuple.rs
new file mode 100644
index 000000000..59e2695de
--- /dev/null
+++ b/src/test/ui/parser/recover-tuple.rs
@@ -0,0 +1,11 @@
+fn main() {
+ // no complaints about the tuple not matching the expected type
+ let x: (usize, usize, usize) = (3, .=.);
+ //~^ ERROR expected expression, found `.`
+ // verify that the parser recovers:
+ let y: usize = ""; //~ ERROR mismatched types
+ // no complaints about the type
+ foo(x);
+}
+
+fn foo(_: (usize, usize, usize)) {}
diff --git a/src/test/ui/parser/recover-tuple.stderr b/src/test/ui/parser/recover-tuple.stderr
new file mode 100644
index 000000000..88891b54b
--- /dev/null
+++ b/src/test/ui/parser/recover-tuple.stderr
@@ -0,0 +1,17 @@
+error: expected expression, found `.`
+ --> $DIR/recover-tuple.rs:3:40
+ |
+LL | let x: (usize, usize, usize) = (3, .=.);
+ | ^ expected expression
+
+error[E0308]: mismatched types
+ --> $DIR/recover-tuple.rs:6:20
+ |
+LL | let y: usize = "";
+ | ----- ^^ expected `usize`, found `&str`
+ | |
+ | expected due to this
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/recovered-struct-variant.rs b/src/test/ui/parser/recovered-struct-variant.rs
new file mode 100644
index 000000000..5b195dcc3
--- /dev/null
+++ b/src/test/ui/parser/recovered-struct-variant.rs
@@ -0,0 +1,13 @@
+enum Foo {
+ A { a, b: usize }
+ //~^ ERROR expected `:`, found `,`
+}
+
+fn main() {
+ // no complaints about non-existing fields
+ let f = Foo::A { a:3, b: 4};
+ match f {
+ // no complaints about non-existing fields
+ Foo::A {a, b} => {}
+ }
+}
diff --git a/src/test/ui/parser/recovered-struct-variant.stderr b/src/test/ui/parser/recovered-struct-variant.stderr
new file mode 100644
index 000000000..51aaf8bb3
--- /dev/null
+++ b/src/test/ui/parser/recovered-struct-variant.stderr
@@ -0,0 +1,8 @@
+error: expected `:`, found `,`
+ --> $DIR/recovered-struct-variant.rs:2:10
+ |
+LL | A { a, b: usize }
+ | ^ expected `:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/regions-out-of-scope-slice.rs b/src/test/ui/parser/regions-out-of-scope-slice.rs
new file mode 100644
index 000000000..d223619e1
--- /dev/null
+++ b/src/test/ui/parser/regions-out-of-scope-slice.rs
@@ -0,0 +1,11 @@
+// This basically tests the parser's recovery on `'blk` in the wrong place.
+
+fn foo(cond: bool) {
+ let mut x;
+
+ if cond {
+ x = &'blk [1,2,3]; //~ ERROR borrow expressions cannot be annotated with lifetimes
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/regions-out-of-scope-slice.stderr b/src/test/ui/parser/regions-out-of-scope-slice.stderr
new file mode 100644
index 000000000..bbc657ffd
--- /dev/null
+++ b/src/test/ui/parser/regions-out-of-scope-slice.stderr
@@ -0,0 +1,11 @@
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/regions-out-of-scope-slice.rs:7:13
+ |
+LL | x = &'blk [1,2,3];
+ | ^----^^^^^^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-closure-lifetime.rs b/src/test/ui/parser/removed-syntax-closure-lifetime.rs
new file mode 100644
index 000000000..e807a1794
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-closure-lifetime.rs
@@ -0,0 +1,2 @@
+type closure = Box<lt/fn()>;
+//~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, `=`, or `>`, found `/`
diff --git a/src/test/ui/parser/removed-syntax-closure-lifetime.stderr b/src/test/ui/parser/removed-syntax-closure-lifetime.stderr
new file mode 100644
index 000000000..e107c6b78
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-closure-lifetime.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, `=`, or `>`, found `/`
+ --> $DIR/removed-syntax-closure-lifetime.rs:1:22
+ |
+LL | type closure = Box<lt/fn()>;
+ | ^ expected one of 9 possible tokens
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | type closure = Box<lt>/fn()>;
+ | +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-enum-newtype.rs b/src/test/ui/parser/removed-syntax-enum-newtype.rs
new file mode 100644
index 000000000..518f90b2b
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-enum-newtype.rs
@@ -0,0 +1 @@
+enum e = isize; //~ ERROR expected one of `<`, `where`, or `{`, found `=`
diff --git a/src/test/ui/parser/removed-syntax-enum-newtype.stderr b/src/test/ui/parser/removed-syntax-enum-newtype.stderr
new file mode 100644
index 000000000..2daa6249b
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-enum-newtype.stderr
@@ -0,0 +1,8 @@
+error: expected one of `<`, `where`, or `{`, found `=`
+ --> $DIR/removed-syntax-enum-newtype.rs:1:8
+ |
+LL | enum e = isize;
+ | ^ expected one of `<`, `where`, or `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-field-let.rs b/src/test/ui/parser/removed-syntax-field-let.rs
new file mode 100644
index 000000000..6d64de296
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-field-let.rs
@@ -0,0 +1,6 @@
+struct S {
+ let foo: (),
+ //~^ ERROR expected identifier, found keyword `let`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr
new file mode 100644
index 000000000..10be2e045
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-field-let.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found keyword `let`
+ --> $DIR/removed-syntax-field-let.rs:2:5
+ |
+LL | let foo: (),
+ | ^^^ expected identifier, found keyword
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.rs b/src/test/ui/parser/removed-syntax-field-semicolon.rs
new file mode 100644
index 000000000..ac28e21ae
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-field-semicolon.rs
@@ -0,0 +1,6 @@
+struct S {
+ bar: ();
+ //~^ ERROR expected `,`, or `}`, found `;`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.stderr b/src/test/ui/parser/removed-syntax-field-semicolon.stderr
new file mode 100644
index 000000000..fbefeb26a
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-field-semicolon.stderr
@@ -0,0 +1,8 @@
+error: expected `,`, or `}`, found `;`
+ --> $DIR/removed-syntax-field-semicolon.rs:2:12
+ |
+LL | bar: ();
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-fixed-vec.rs b/src/test/ui/parser/removed-syntax-fixed-vec.rs
new file mode 100644
index 000000000..560efecb9
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-fixed-vec.rs
@@ -0,0 +1 @@
+type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
diff --git a/src/test/ui/parser/removed-syntax-fixed-vec.stderr b/src/test/ui/parser/removed-syntax-fixed-vec.stderr
new file mode 100644
index 000000000..a2b97544f
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-fixed-vec.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
+ --> $DIR/removed-syntax-fixed-vec.rs:1:17
+ |
+LL | type v = [isize * 3];
+ | ^ expected one of 7 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-fn-sigil.rs b/src/test/ui/parser/removed-syntax-fn-sigil.rs
new file mode 100644
index 000000000..725843429
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-fn-sigil.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let x: fn~() = || (); //~ ERROR expected `(`, found `~`
+}
diff --git a/src/test/ui/parser/removed-syntax-fn-sigil.stderr b/src/test/ui/parser/removed-syntax-fn-sigil.stderr
new file mode 100644
index 000000000..196a5af47
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-fn-sigil.stderr
@@ -0,0 +1,10 @@
+error: expected `(`, found `~`
+ --> $DIR/removed-syntax-fn-sigil.rs:2:14
+ |
+LL | let x: fn~() = || ();
+ | - ^ expected `(`
+ | |
+ | while parsing the type for `x`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-mode.rs b/src/test/ui/parser/removed-syntax-mode.rs
new file mode 100644
index 000000000..a438db3b0
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-mode.rs
@@ -0,0 +1,4 @@
+fn f(+x: isize) {}
+//~^ ERROR expected parameter name, found `+`
+
+fn main() {}
diff --git a/src/test/ui/parser/removed-syntax-mode.stderr b/src/test/ui/parser/removed-syntax-mode.stderr
new file mode 100644
index 000000000..d0393b379
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-mode.stderr
@@ -0,0 +1,8 @@
+error: expected parameter name, found `+`
+ --> $DIR/removed-syntax-mode.rs:1:6
+ |
+LL | fn f(+x: isize) {}
+ | ^ expected parameter name
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-mut-vec-expr.rs b/src/test/ui/parser/removed-syntax-mut-vec-expr.rs
new file mode 100644
index 000000000..2ee95db5a
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-mut-vec-expr.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let v = [mut 1, 2, 3, 4]; //~ ERROR expected expression, found keyword `mut`
+}
diff --git a/src/test/ui/parser/removed-syntax-mut-vec-expr.stderr b/src/test/ui/parser/removed-syntax-mut-vec-expr.stderr
new file mode 100644
index 000000000..313420fb9
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-mut-vec-expr.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found keyword `mut`
+ --> $DIR/removed-syntax-mut-vec-expr.rs:2:14
+ |
+LL | let v = [mut 1, 2, 3, 4];
+ | ^^^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-mut-vec-ty.rs b/src/test/ui/parser/removed-syntax-mut-vec-ty.rs
new file mode 100644
index 000000000..923a7ea37
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-mut-vec-ty.rs
@@ -0,0 +1 @@
+type v = [mut isize]; //~ ERROR expected type, found keyword `mut`
diff --git a/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr
new file mode 100644
index 000000000..02b518e25
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-mut-vec-ty.stderr
@@ -0,0 +1,8 @@
+error: expected type, found keyword `mut`
+ --> $DIR/removed-syntax-mut-vec-ty.rs:1:11
+ |
+LL | type v = [mut isize];
+ | ^^^ expected type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-ptr-lifetime.rs b/src/test/ui/parser/removed-syntax-ptr-lifetime.rs
new file mode 100644
index 000000000..cc69af44a
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-ptr-lifetime.rs
@@ -0,0 +1 @@
+type bptr = &lifetime/isize; //~ ERROR expected one of `!`, `(`, `::`, `;`, `<`, or `where`, found `/`
diff --git a/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr b/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr
new file mode 100644
index 000000000..914de43e6
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `(`, `::`, `;`, `<`, or `where`, found `/`
+ --> $DIR/removed-syntax-ptr-lifetime.rs:1:22
+ |
+LL | type bptr = &lifetime/isize;
+ | ^ expected one of `!`, `(`, `::`, `;`, `<`, or `where`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-record.rs b/src/test/ui/parser/removed-syntax-record.rs
new file mode 100644
index 000000000..d1d91c8f7
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-record.rs
@@ -0,0 +1 @@
+type t = { f: () }; //~ ERROR expected type, found `{`
diff --git a/src/test/ui/parser/removed-syntax-record.stderr b/src/test/ui/parser/removed-syntax-record.stderr
new file mode 100644
index 000000000..0a1655840
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-record.stderr
@@ -0,0 +1,8 @@
+error: expected type, found `{`
+ --> $DIR/removed-syntax-record.rs:1:10
+ |
+LL | type t = { f: () };
+ | ^ expected type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-static-fn.rs b/src/test/ui/parser/removed-syntax-static-fn.rs
new file mode 100644
index 000000000..cd643b874
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-static-fn.rs
@@ -0,0 +1,10 @@
+struct S;
+
+impl S {
+ static fn f() {}
+ //~^ ERROR expected identifier, found keyword `fn`
+ //~| ERROR expected one of `:`, `;`, or `=`
+ //~| ERROR missing type for `static` item
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr
new file mode 100644
index 000000000..04e34dc16
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-static-fn.stderr
@@ -0,0 +1,25 @@
+error: expected identifier, found keyword `fn`
+ --> $DIR/removed-syntax-static-fn.rs:4:12
+ |
+LL | static fn f() {}
+ | ^^ expected identifier, found keyword
+
+error: expected one of `:`, `;`, or `=`, found `f`
+ --> $DIR/removed-syntax-static-fn.rs:4:15
+ |
+LL | impl S {
+ | - while parsing this item list starting here
+LL | static fn f() {}
+ | ^ expected one of `:`, `;`, or `=`
+...
+LL | }
+ | - the item list ends here
+
+error: missing type for `static` item
+ --> $DIR/removed-syntax-static-fn.rs:4:12
+ |
+LL | static fn f() {}
+ | ^^ help: provide a type for the item: `r#fn: <type>`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-expr.rs b/src/test/ui/parser/removed-syntax-uniq-mut-expr.rs
new file mode 100644
index 000000000..08ef4b432
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-uniq-mut-expr.rs
@@ -0,0 +1,3 @@
+fn main() {
+ let a_box = box mut 42; //~ ERROR expected expression, found keyword `mut`
+}
diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr b/src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr
new file mode 100644
index 000000000..63d2fdb8c
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-uniq-mut-expr.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found keyword `mut`
+ --> $DIR/removed-syntax-uniq-mut-expr.rs:2:21
+ |
+LL | let a_box = box mut 42;
+ | ^^^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs b/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs
new file mode 100644
index 000000000..a8dee5bbd
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.rs
@@ -0,0 +1,2 @@
+type mut_box = Box<mut isize>;
+//~^ ERROR expected one of `>`, a const expression, lifetime, or type, found keyword `mut`
diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr
new file mode 100644
index 000000000..39db0be9f
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr
@@ -0,0 +1,8 @@
+error: expected one of `>`, a const expression, lifetime, or type, found keyword `mut`
+ --> $DIR/removed-syntax-uniq-mut-ty.rs:1:20
+ |
+LL | type mut_box = Box<mut isize>;
+ | ^^^ expected one of `>`, a const expression, lifetime, or type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-with-1.rs b/src/test/ui/parser/removed-syntax-with-1.rs
new file mode 100644
index 000000000..2c1e152dc
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-with-1.rs
@@ -0,0 +1,10 @@
+fn main() {
+ struct S {
+ foo: (),
+ bar: (),
+ }
+
+ let a = S { foo: (), bar: () };
+ let b = S { foo: () with a, bar: () };
+ //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
+}
diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr
new file mode 100644
index 000000000..c3f747b61
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-with-1.stderr
@@ -0,0 +1,11 @@
+error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
+ --> $DIR/removed-syntax-with-1.rs:8:25
+ |
+LL | let b = S { foo: () with a, bar: () };
+ | - -^^^^ expected one of `,`, `.`, `?`, `}`, or an operator
+ | | |
+ | | help: try adding a comma: `,`
+ | while parsing this struct
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/removed-syntax-with-2.rs b/src/test/ui/parser/removed-syntax-with-2.rs
new file mode 100644
index 000000000..451057c66
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-with-2.rs
@@ -0,0 +1,11 @@
+fn main() {
+ struct S {
+ foo: (),
+ bar: (),
+ }
+
+ let a = S { foo: (), bar: () };
+ let b = S { foo: (), with a };
+ //~^ ERROR expected one of `,`, `:`, or `}`, found `a`
+ //~| ERROR missing field `bar` in initializer of `S`
+}
diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr
new file mode 100644
index 000000000..c6ae1ce67
--- /dev/null
+++ b/src/test/ui/parser/removed-syntax-with-2.stderr
@@ -0,0 +1,17 @@
+error: expected one of `,`, `:`, or `}`, found `a`
+ --> $DIR/removed-syntax-with-2.rs:8:31
+ |
+LL | let b = S { foo: (), with a };
+ | - ^ expected one of `,`, `:`, or `}`
+ | |
+ | while parsing this struct
+
+error[E0063]: missing field `bar` in initializer of `S`
+ --> $DIR/removed-syntax-with-2.rs:8:13
+ |
+LL | let b = S { foo: (), with a };
+ | ^ missing `bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs
new file mode 100644
index 000000000..f29fd7a54
--- /dev/null
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs
@@ -0,0 +1,36 @@
+fn main() {
+ false == false == false;
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP split the comparison into two
+
+ false == 0 < 2;
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP parenthesize the comparison
+
+ f<X>();
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+
+ f<Result<Option<X>, Option<Option<X>>>(1, 2);
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+
+ let _ = f<u8, i8>();
+ //~^ ERROR expected one of
+ //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+
+ let _ = f<'_, i8>();
+ //~^ ERROR expected one of
+ //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ //~| ERROR expected
+
+ f<'_>();
+ //~^ comparison operators cannot be chained
+ //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ //~| ERROR expected
+
+ let _ = f<u8>;
+ //~^ ERROR comparison operators cannot be chained
+ //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ //~| HELP or use `(...)` if you meant to specify fn arguments
+}
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
new file mode 100644
index 000000000..0bf52854e
--- /dev/null
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
@@ -0,0 +1,100 @@
+error: comparison operators cannot be chained
+ --> $DIR/require-parens-for-chained-comparison.rs:2:11
+ |
+LL | false == false == false;
+ | ^^ ^^
+ |
+help: split the comparison into two
+ |
+LL | false == false && false == false;
+ | ++++++++
+
+error: comparison operators cannot be chained
+ --> $DIR/require-parens-for-chained-comparison.rs:6:11
+ |
+LL | false == 0 < 2;
+ | ^^ ^
+ |
+help: parenthesize the comparison
+ |
+LL | false == (0 < 2);
+ | + +
+
+error: comparison operators cannot be chained
+ --> $DIR/require-parens-for-chained-comparison.rs:10:6
+ |
+LL | f<X>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | f::<X>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/require-parens-for-chained-comparison.rs:14:6
+ |
+LL | f<Result<Option<X>, Option<Option<X>>>(1, 2);
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | f::<Result<Option<X>, Option<Option<X>>>(1, 2);
+ | ++
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `,`
+ --> $DIR/require-parens-for-chained-comparison.rs:18:17
+ |
+LL | let _ = f<u8, i8>();
+ | ^ expected one of 8 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | let _ = f::<u8, i8>();
+ | ++
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/require-parens-for-chained-comparison.rs:22:17
+ |
+LL | let _ = f<'_, i8>();
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+
+error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, or an operator, found `,`
+ --> $DIR/require-parens-for-chained-comparison.rs:22:17
+ |
+LL | let _ = f<'_, i8>();
+ | ^ expected one of 9 possible tokens
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | let _ = f::<'_, i8>();
+ | ++
+
+error: expected `while`, `for`, `loop` or `{` after a label
+ --> $DIR/require-parens-for-chained-comparison.rs:27:9
+ |
+LL | f<'_>();
+ | ^ expected `while`, `for`, `loop` or `{` after a label
+
+error: comparison operators cannot be chained
+ --> $DIR/require-parens-for-chained-comparison.rs:27:6
+ |
+LL | f<'_>();
+ | ^ ^
+ |
+help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ |
+LL | f::<'_>();
+ | ++
+
+error: comparison operators cannot be chained
+ --> $DIR/require-parens-for-chained-comparison.rs:32:14
+ |
+LL | let _ = f<u8>;
+ | ^ ^
+ |
+ = help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+ = help: or use `(...)` if you meant to specify fn arguments
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/parser/self-in-function-arg.rs b/src/test/ui/parser/self-in-function-arg.rs
new file mode 100644
index 000000000..6172ffe1b
--- /dev/null
+++ b/src/test/ui/parser/self-in-function-arg.rs
@@ -0,0 +1,3 @@
+fn foo(x:i32, self: i32) -> i32 { self } //~ ERROR unexpected `self` parameter in function
+
+fn main() {}
diff --git a/src/test/ui/parser/self-in-function-arg.stderr b/src/test/ui/parser/self-in-function-arg.stderr
new file mode 100644
index 000000000..47d8381b0
--- /dev/null
+++ b/src/test/ui/parser/self-in-function-arg.stderr
@@ -0,0 +1,8 @@
+error: unexpected `self` parameter in function
+ --> $DIR/self-in-function-arg.rs:1:15
+ |
+LL | fn foo(x:i32, self: i32) -> i32 { self }
+ | ^^^^ must be the first parameter of an associated function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/self-param-semantic-fail.rs b/src/test/ui/parser/self-param-semantic-fail.rs
new file mode 100644
index 000000000..621aab279
--- /dev/null
+++ b/src/test/ui/parser/self-param-semantic-fail.rs
@@ -0,0 +1,64 @@
+// This test ensures that `self` is semantically rejected
+// in contexts with `FnDecl` but outside of associated `fn`s.
+// FIXME(Centril): For now closures are an exception.
+
+fn main() {}
+
+fn free() {
+ fn f1(self) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f2(mut self) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f3(&self) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f4(&mut self) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f5<'a>(&'a self) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f6<'a>(&'a mut self) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f7(self: u8) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f8(mut self: u8) {}
+ //~^ ERROR `self` parameter is only allowed in associated functions
+}
+
+extern "C" {
+ fn f1(self);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f2(mut self);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ //~| ERROR patterns aren't allowed in
+ fn f3(&self);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f4(&mut self);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f5<'a>(&'a self);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f6<'a>(&'a mut self);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f7(self: u8);
+ //~^ ERROR `self` parameter is only allowed in associated functions
+ fn f8(mut self: u8);
+//~^ ERROR `self` parameter is only allowed in associated functions
+//~| ERROR patterns aren't allowed in
+}
+
+type X1 = fn(self);
+//~^ ERROR `self` parameter is only allowed in associated functions
+type X2 = fn(mut self);
+//~^ ERROR `self` parameter is only allowed in associated functions
+//~| ERROR patterns aren't allowed in
+type X3 = fn(&self);
+//~^ ERROR `self` parameter is only allowed in associated functions
+type X4 = fn(&mut self);
+//~^ ERROR `self` parameter is only allowed in associated functions
+type X5 = for<'a> fn(&'a self);
+//~^ ERROR `self` parameter is only allowed in associated functions
+type X6 = for<'a> fn(&'a mut self);
+//~^ ERROR `self` parameter is only allowed in associated functions
+type X7 = fn(self: u8);
+//~^ ERROR `self` parameter is only allowed in associated functions
+type X8 = fn(mut self: u8);
+//~^ ERROR `self` parameter is only allowed in associated functions
+//~| ERROR patterns aren't allowed in
diff --git a/src/test/ui/parser/self-param-semantic-fail.stderr b/src/test/ui/parser/self-param-semantic-fail.stderr
new file mode 100644
index 000000000..e5d679773
--- /dev/null
+++ b/src/test/ui/parser/self-param-semantic-fail.stderr
@@ -0,0 +1,220 @@
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:8:11
+ |
+LL | fn f1(self) {}
+ | ^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:10:11
+ |
+LL | fn f2(mut self) {}
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:12:11
+ |
+LL | fn f3(&self) {}
+ | ^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:14:11
+ |
+LL | fn f4(&mut self) {}
+ | ^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:16:15
+ |
+LL | fn f5<'a>(&'a self) {}
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:18:15
+ |
+LL | fn f6<'a>(&'a mut self) {}
+ | ^^^^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:20:11
+ |
+LL | fn f7(self: u8) {}
+ | ^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:22:11
+ |
+LL | fn f8(mut self: u8) {}
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:27:11
+ |
+LL | fn f1(self);
+ | ^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:29:11
+ |
+LL | fn f2(mut self);
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0130]: patterns aren't allowed in foreign function declarations
+ --> $DIR/self-param-semantic-fail.rs:29:11
+ |
+LL | fn f2(mut self);
+ | ^^^^^^^^ pattern not allowed in foreign function
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:32:11
+ |
+LL | fn f3(&self);
+ | ^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:34:11
+ |
+LL | fn f4(&mut self);
+ | ^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:36:15
+ |
+LL | fn f5<'a>(&'a self);
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:38:15
+ |
+LL | fn f6<'a>(&'a mut self);
+ | ^^^^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:40:11
+ |
+LL | fn f7(self: u8);
+ | ^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:42:11
+ |
+LL | fn f8(mut self: u8);
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0130]: patterns aren't allowed in foreign function declarations
+ --> $DIR/self-param-semantic-fail.rs:42:11
+ |
+LL | fn f8(mut self: u8);
+ | ^^^^^^^^ pattern not allowed in foreign function
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:47:14
+ |
+LL | type X1 = fn(self);
+ | ^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:49:14
+ |
+LL | type X2 = fn(mut self);
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0561]: patterns aren't allowed in function pointer types
+ --> $DIR/self-param-semantic-fail.rs:49:14
+ |
+LL | type X2 = fn(mut self);
+ | ^^^^^^^^
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:52:14
+ |
+LL | type X3 = fn(&self);
+ | ^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:54:14
+ |
+LL | type X4 = fn(&mut self);
+ | ^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:56:22
+ |
+LL | type X5 = for<'a> fn(&'a self);
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:58:22
+ |
+LL | type X6 = for<'a> fn(&'a mut self);
+ | ^^^^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:60:14
+ |
+LL | type X7 = fn(self: u8);
+ | ^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/self-param-semantic-fail.rs:62:14
+ |
+LL | type X8 = fn(mut self: u8);
+ | ^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0561]: patterns aren't allowed in function pointer types
+ --> $DIR/self-param-semantic-fail.rs:62:14
+ |
+LL | type X8 = fn(mut self: u8);
+ | ^^^^^^^^
+
+error: aborting due to 28 previous errors
+
+Some errors have detailed explanations: E0130, E0561.
+For more information about an error, try `rustc --explain E0130`.
diff --git a/src/test/ui/parser/self-param-syntactic-pass.rs b/src/test/ui/parser/self-param-syntactic-pass.rs
new file mode 100644
index 000000000..d7bb7863c
--- /dev/null
+++ b/src/test/ui/parser/self-param-syntactic-pass.rs
@@ -0,0 +1,66 @@
+// This test ensures that `self` is syntactically accepted in all places an `FnDecl` is parsed.
+// FIXME(Centril): For now closures are an exception.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn free() {
+ fn f(self) {}
+ fn f(mut self) {}
+ fn f(&self) {}
+ fn f(&mut self) {}
+ fn f(&'a self) {}
+ fn f(&'a mut self) {}
+ fn f(self: u8) {}
+ fn f(mut self: u8) {}
+}
+
+#[cfg(FALSE)]
+extern "C" {
+ fn f(self);
+ fn f(mut self);
+ fn f(&self);
+ fn f(&mut self);
+ fn f(&'a self);
+ fn f(&'a mut self);
+ fn f(self: u8);
+ fn f(mut self: u8);
+}
+
+#[cfg(FALSE)]
+trait X {
+ fn f(self) {}
+ fn f(mut self) {}
+ fn f(&self) {}
+ fn f(&mut self) {}
+ fn f(&'a self) {}
+ fn f(&'a mut self) {}
+ fn f(self: u8) {}
+ fn f(mut self: u8) {}
+}
+
+#[cfg(FALSE)]
+impl X for Y {
+ fn f(self) {}
+ fn f(mut self) {}
+ fn f(&self) {}
+ fn f(&mut self) {}
+ fn f(&'a self) {}
+ fn f(&'a mut self) {}
+ fn f(self: u8) {}
+ fn f(mut self: u8) {}
+}
+
+#[cfg(FALSE)]
+impl X for Y {
+ type X = fn(self);
+ type X = fn(mut self);
+ type X = fn(&self);
+ type X = fn(&mut self);
+ type X = fn(&'a self);
+ type X = fn(&'a mut self);
+ type X = fn(self: u8);
+ type X = fn(mut self: u8);
+}
diff --git a/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs b/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs
new file mode 100644
index 000000000..ee14c55d2
--- /dev/null
+++ b/src/test/ui/parser/several-carriage-returns-in-doc-comment.rs
@@ -0,0 +1,10 @@
+// Issue #62863
+// ignore-tidy-cr
+
+// Note: if you see ^M in this file, that's how your editor renders literal `\r`
+
+/// This do c comment contains three isolated `\r` symbols
+//~^ ERROR bare CR not allowed in doc-comment
+//~| ERROR bare CR not allowed in doc-comment
+//~| ERROR bare CR not allowed in doc-comment
+fn main() {}
diff --git a/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr b/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr
new file mode 100644
index 000000000..07066fc22
--- /dev/null
+++ b/src/test/ui/parser/several-carriage-returns-in-doc-comment.stderr
@@ -0,0 +1,20 @@
+error: bare CR not allowed in doc-comment
+ --> $DIR/several-carriage-returns-in-doc-comment.rs:6:12
+ |
+LL | /// This do c comment contains three isolated `\r` symbols
+ | ^
+
+error: bare CR not allowed in doc-comment
+ --> $DIR/several-carriage-returns-in-doc-comment.rs:6:32
+ |
+LL | /// This do c comment contains three isolated `\r` symbols
+ | ^
+
+error: bare CR not allowed in doc-comment
+ --> $DIR/several-carriage-returns-in-doc-comment.rs:6:52
+ |
+LL | /// This do c comment contains three isolated `\r` symbols
+ | ^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs
new file mode 100644
index 000000000..a25051808
--- /dev/null
+++ b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.rs
@@ -0,0 +1,2 @@
+
+#!B //~ expected `[`, found `B`
diff --git a/src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr
new file mode 100644
index 000000000..896a9dc83
--- /dev/null
+++ b/src/test/ui/parser/shebang/issue-71471-ignore-tidy.stderr
@@ -0,0 +1,8 @@
+error: expected `[`, found `B`
+ --> $DIR/issue-71471-ignore-tidy.rs:2:3
+ |
+LL | #!B
+ | ^ expected `[`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/shebang/multiline-attrib.rs b/src/test/ui/parser/shebang/multiline-attrib.rs
new file mode 100644
index 000000000..931c94c7f
--- /dev/null
+++ b/src/test/ui/parser/shebang/multiline-attrib.rs
@@ -0,0 +1,7 @@
+#!
+[allow(unused_variables)]
+// check-pass
+
+fn main() {
+ let x = 5;
+}
diff --git a/src/test/ui/parser/shebang/regular-attrib.rs b/src/test/ui/parser/shebang/regular-attrib.rs
new file mode 100644
index 000000000..ca8fb0830
--- /dev/null
+++ b/src/test/ui/parser/shebang/regular-attrib.rs
@@ -0,0 +1,5 @@
+#![allow(unused_variables)]
+// check-pass
+fn main() {
+ let x = 5;
+}
diff --git a/src/test/ui/parser/shebang/shebang-and-attrib.rs b/src/test/ui/parser/shebang/shebang-and-attrib.rs
new file mode 100644
index 000000000..61b89c655
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-and-attrib.rs
@@ -0,0 +1,9 @@
+#!/usr/bin/env run-cargo-script
+
+// check-pass
+#![allow(unused_variables)]
+
+
+fn main() {
+ let x = 5;
+}
diff --git a/src/test/ui/parser/shebang/shebang-comment.rs b/src/test/ui/parser/shebang/shebang-comment.rs
new file mode 100644
index 000000000..2b1ab0c57
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-comment.rs
@@ -0,0 +1,6 @@
+#!//bin/bash
+
+// check-pass
+fn main() {
+ println!("a valid shebang (that is also a rust comment)")
+}
diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.rs b/src/test/ui/parser/shebang/shebang-doc-comment.rs
new file mode 100644
index 000000000..72866753e
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-doc-comment.rs
@@ -0,0 +1,3 @@
+#!///bin/bash
+[allow(unused_variables)]
+//~^ ERROR expected item, found `[`
diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.stderr b/src/test/ui/parser/shebang/shebang-doc-comment.stderr
new file mode 100644
index 000000000..2227d45ec
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-doc-comment.stderr
@@ -0,0 +1,8 @@
+error: expected item, found `[`
+ --> $DIR/shebang-doc-comment.rs:2:1
+ |
+LL | [allow(unused_variables)]
+ | ^ expected item
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/shebang/shebang-empty.rs b/src/test/ui/parser/shebang/shebang-empty.rs
new file mode 100644
index 000000000..e38cc637e
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-empty.rs
@@ -0,0 +1,4 @@
+#!
+
+// check-pass
+fn main() {}
diff --git a/src/test/ui/parser/shebang/shebang-must-start-file.rs b/src/test/ui/parser/shebang/shebang-must-start-file.rs
new file mode 100644
index 000000000..e0392572d
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-must-start-file.rs
@@ -0,0 +1,6 @@
+// something on the first line for tidy
+#!/bin/bash //~ expected `[`, found `/`
+
+fn main() {
+ println!("ok!");
+}
diff --git a/src/test/ui/parser/shebang/shebang-must-start-file.stderr b/src/test/ui/parser/shebang/shebang-must-start-file.stderr
new file mode 100644
index 000000000..50543e8bd
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-must-start-file.stderr
@@ -0,0 +1,8 @@
+error: expected `[`, found `/`
+ --> $DIR/shebang-must-start-file.rs:2:3
+ |
+LL | #!/bin/bash
+ | ^ expected `[`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/shebang/shebang-space.rs b/src/test/ui/parser/shebang/shebang-space.rs
new file mode 100644
index 000000000..0978b759d
--- /dev/null
+++ b/src/test/ui/parser/shebang/shebang-space.rs
@@ -0,0 +1,5 @@
+#!
+
+// check-pass
+// ignore-tidy-end-whitespace
+fn main() {}
diff --git a/src/test/ui/parser/shebang/sneaky-attrib.rs b/src/test/ui/parser/shebang/sneaky-attrib.rs
new file mode 100644
index 000000000..b406cc3aa
--- /dev/null
+++ b/src/test/ui/parser/shebang/sneaky-attrib.rs
@@ -0,0 +1,16 @@
+#!//bin/bash
+
+
+// This could not possibly be a shebang & also a valid rust file, since a Rust file
+// can't start with `[`
+/*
+ [ (mixing comments to also test that we ignore both types of comments)
+
+ */
+
+[allow(unused_variables)]
+
+// check-pass
+fn main() {
+ let x = 5;
+}
diff --git a/src/test/ui/parser/shebang/valid-shebang.rs b/src/test/ui/parser/shebang/valid-shebang.rs
new file mode 100644
index 000000000..e480d3da3
--- /dev/null
+++ b/src/test/ui/parser/shebang/valid-shebang.rs
@@ -0,0 +1,6 @@
+#!/usr/bin/env run-cargo-script
+
+// check-pass
+fn main() {
+ println!("Hello World!");
+}
diff --git a/src/test/ui/parser/similar-tokens.rs b/src/test/ui/parser/similar-tokens.rs
new file mode 100644
index 000000000..e3024c61a
--- /dev/null
+++ b/src/test/ui/parser/similar-tokens.rs
@@ -0,0 +1,11 @@
+#![allow(unused_imports)]
+
+pub mod x {
+ pub struct A;
+ pub struct B;
+}
+
+// `.` is similar to `,` so list parsing should continue to closing `}`
+use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.`
+
+fn main() {}
diff --git a/src/test/ui/parser/similar-tokens.stderr b/src/test/ui/parser/similar-tokens.stderr
new file mode 100644
index 000000000..90acfc052
--- /dev/null
+++ b/src/test/ui/parser/similar-tokens.stderr
@@ -0,0 +1,11 @@
+error: expected one of `,`, `::`, `as`, or `}`, found `.`
+ --> $DIR/similar-tokens.rs:9:10
+ |
+LL | use x::{A. B};
+ | ^
+ | |
+ | expected one of `,`, `::`, `as`, or `}`
+ | help: missing `,`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/stmt_expr_attrs_placement.rs b/src/test/ui/parser/stmt_expr_attrs_placement.rs
new file mode 100644
index 000000000..5e9d29a15
--- /dev/null
+++ b/src/test/ui/parser/stmt_expr_attrs_placement.rs
@@ -0,0 +1,38 @@
+#![feature(stmt_expr_attributes)]
+
+// Test that various placements of the inner attribute are parsed correctly,
+// or not.
+
+fn main() {
+ let a = #![allow(warnings)] (1, 2);
+ //~^ ERROR an inner attribute is not permitted in this context
+
+ let b = (#![allow(warnings)] 1, 2);
+ //~^ ERROR an inner attribute is not permitted in this context
+
+ let c = {
+ #![allow(warnings)]
+ (#![allow(warnings)] 1, 2)
+ //~^ ERROR an inner attribute is not permitted in this context
+ };
+
+ let d = {
+ #![allow(warnings)]
+ let e = (#![allow(warnings)] 1, 2);
+ //~^ ERROR an inner attribute is not permitted in this context
+ e
+ };
+
+ let e = [#![allow(warnings)] 1, 2];
+ //~^ ERROR an inner attribute is not permitted in this context
+
+ let f = [#![allow(warnings)] 1; 0];
+ //~^ ERROR an inner attribute is not permitted in this context
+
+ let g = match true { #![allow(warnings)] _ => {} };
+
+
+ struct MyStruct { field: u8 }
+ let h = MyStruct { #![allow(warnings)] field: 0 };
+ //~^ ERROR an inner attribute is not permitted in this context
+}
diff --git a/src/test/ui/parser/stmt_expr_attrs_placement.stderr b/src/test/ui/parser/stmt_expr_attrs_placement.stderr
new file mode 100644
index 000000000..bf4005698
--- /dev/null
+++ b/src/test/ui/parser/stmt_expr_attrs_placement.stderr
@@ -0,0 +1,65 @@
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:7:13
+ |
+LL | let a = #![allow(warnings)] (1, 2);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:10:14
+ |
+LL | let b = (#![allow(warnings)] 1, 2);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:15:10
+ |
+LL | (#![allow(warnings)] 1, 2)
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:21:18
+ |
+LL | let e = (#![allow(warnings)] 1, 2);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:26:14
+ |
+LL | let e = [#![allow(warnings)] 1, 2];
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:29:14
+ |
+LL | let f = [#![allow(warnings)] 1; 0];
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+ --> $DIR/stmt_expr_attrs_placement.rs:36:24
+ |
+LL | let h = MyStruct { #![allow(warnings)] field: 0 };
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+ = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/ui/parser/stripped-nested-outline-mod-pass.rs b/src/test/ui/parser/stripped-nested-outline-mod-pass.rs
new file mode 100644
index 000000000..1b4669a43
--- /dev/null
+++ b/src/test/ui/parser/stripped-nested-outline-mod-pass.rs
@@ -0,0 +1,13 @@
+// Expansion drives parsing, so conditional compilation will strip
+// out outline modules and we will never attempt parsing them.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+mod foo {
+ mod bar {
+ mod baz; // This was an error before.
+ }
+}
diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed b/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed
new file mode 100644
index 000000000..28191b826
--- /dev/null
+++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.fixed
@@ -0,0 +1,35 @@
+// run-rustfix
+#![allow(dead_code)]
+
+enum E {
+ A,
+}
+
+struct S {
+ field1: i32, //~ ERROR default values on `struct` fields aren't supported
+ field2: E, //~ ERROR default values on `struct` fields aren't supported
+ field3: i32, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32, //~ ERROR default values on `struct` fields aren't supported
+ field5: E, //~ ERROR default values on `struct` fields aren't supported
+ field6: E, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S1 {
+ field1: i32, //~ ERROR expected `,`, or `}`, found `field2`
+ field2: E, //~ ERROR expected `,`, or `}`, found `field3`
+ field3: i32, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32, //~ ERROR default values on `struct` fields aren't supported
+ field5: E, //~ ERROR default values on `struct` fields aren't supported
+ field6: E, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S2 {
+ field1 : i32, //~ ERROR expected `:`, found `=`
+ field2: E, //~ ERROR expected `:`, found `;`
+}
+
+const fn foo(_: i32) -> E {
+ E::A
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs b/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs
new file mode 100644
index 000000000..924cb08a9
--- /dev/null
+++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.rs
@@ -0,0 +1,35 @@
+// run-rustfix
+#![allow(dead_code)]
+
+enum E {
+ A,
+}
+
+struct S {
+ field1: i32 = 42, //~ ERROR default values on `struct` fields aren't supported
+ field2: E = E::A, //~ ERROR default values on `struct` fields aren't supported
+ field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported
+ field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported
+ field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S1 {
+ field1: i32 //~ ERROR expected `,`, or `}`, found `field2`
+ field2: E //~ ERROR expected `,`, or `}`, found `field3`
+ field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported
+ field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported
+ field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S2 {
+ field1 = i32, //~ ERROR expected `:`, found `=`
+ field2; E, //~ ERROR expected `:`, found `;`
+}
+
+const fn foo(_: i32) -> E {
+ E::A
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr b/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr
new file mode 100644
index 000000000..7f16ebcfc
--- /dev/null
+++ b/src/test/ui/parser/struct-default-values-and-missing-field-separator.stderr
@@ -0,0 +1,92 @@
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:9:16
+ |
+LL | field1: i32 = 42,
+ | ^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:10:14
+ |
+LL | field2: E = E::A,
+ | ^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:11:16
+ |
+LL | field3: i32 = 1 + 2,
+ | ^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:12:16
+ |
+LL | field4: i32 = { 1 + 2 },
+ | ^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:13:14
+ |
+LL | field5: E = foo(42),
+ | ^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:14:14
+ |
+LL | field6: E = { foo(42) },
+ | ^^^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: expected `,`, or `}`, found `field2`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:18:16
+ |
+LL | field1: i32
+ | ^ help: try adding a comma: `,`
+
+error: expected `,`, or `}`, found `field3`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:19:14
+ |
+LL | field2: E
+ | ^ help: try adding a comma: `,`
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:20:16
+ |
+LL | field3: i32 = 1 + 2,
+ | ^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:21:16
+ |
+LL | field4: i32 = { 1 + 2 },
+ | ^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:22:14
+ |
+LL | field5: E = foo(42),
+ | ^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:23:14
+ |
+LL | field6: E = { foo(42) },
+ | ^^^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: expected `:`, found `=`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:27:12
+ |
+LL | field1 = i32,
+ | ^
+ | |
+ | expected `:`
+ | help: field names and their types are separated with `:`
+
+error: expected `:`, found `;`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:28:11
+ |
+LL | field2; E,
+ | ^
+ | |
+ | expected `:`
+ | help: field names and their types are separated with `:`
+
+error: aborting due to 14 previous errors
+
diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.rs b/src/test/ui/parser/struct-field-numeric-shorthand.rs
new file mode 100644
index 000000000..645abd9c7
--- /dev/null
+++ b/src/test/ui/parser/struct-field-numeric-shorthand.rs
@@ -0,0 +1,9 @@
+struct Rgb(u8, u8, u8);
+
+fn main() {
+ let _ = Rgb { 0, 1, 2 };
+ //~^ ERROR expected identifier, found `0`
+ //~| ERROR expected identifier, found `1`
+ //~| ERROR expected identifier, found `2`
+ //~| ERROR missing fields `0`, `1` and `2` in initializer of `Rgb`
+}
diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.stderr b/src/test/ui/parser/struct-field-numeric-shorthand.stderr
new file mode 100644
index 000000000..bfb8a931b
--- /dev/null
+++ b/src/test/ui/parser/struct-field-numeric-shorthand.stderr
@@ -0,0 +1,33 @@
+error: expected identifier, found `0`
+ --> $DIR/struct-field-numeric-shorthand.rs:4:19
+ |
+LL | let _ = Rgb { 0, 1, 2 };
+ | --- ^ expected identifier
+ | |
+ | while parsing this struct
+
+error: expected identifier, found `1`
+ --> $DIR/struct-field-numeric-shorthand.rs:4:22
+ |
+LL | let _ = Rgb { 0, 1, 2 };
+ | --- ^ expected identifier
+ | |
+ | while parsing this struct
+
+error: expected identifier, found `2`
+ --> $DIR/struct-field-numeric-shorthand.rs:4:25
+ |
+LL | let _ = Rgb { 0, 1, 2 };
+ | --- ^ expected identifier
+ | |
+ | while parsing this struct
+
+error[E0063]: missing fields `0`, `1` and `2` in initializer of `Rgb`
+ --> $DIR/struct-field-numeric-shorthand.rs:4:13
+ |
+LL | let _ = Rgb { 0, 1, 2 };
+ | ^^^ missing `0`, `1` and `2`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/parser/struct-literal-in-for.rs b/src/test/ui/parser/struct-literal-in-for.rs
new file mode 100644
index 000000000..3227ae37b
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-for.rs
@@ -0,0 +1,17 @@
+struct Foo {
+ x: isize,
+}
+
+impl Foo {
+ fn hi(&self) -> bool {
+ true
+ }
+}
+
+fn main() {
+ for x in Foo { //~ ERROR struct literals are not allowed here
+ x: 3 //~^ ERROR `bool` is not an iterator
+ }.hi() {
+ println!("yo");
+ }
+}
diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr
new file mode 100644
index 000000000..4b191710c
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-for.stderr
@@ -0,0 +1,31 @@
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-in-for.rs:12:14
+ |
+LL | for x in Foo {
+ | ______________^
+LL | | x: 3
+LL | | }.hi() {
+ | |_____^
+ |
+help: surround the struct literal with parentheses
+ |
+LL ~ for x in (Foo {
+LL | x: 3
+LL ~ }).hi() {
+ |
+
+error[E0277]: `bool` is not an iterator
+ --> $DIR/struct-literal-in-for.rs:12:14
+ |
+LL | for x in Foo {
+ | ______________^
+LL | | x: 3
+LL | | }.hi() {
+ | |__________^ `bool` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `bool`
+ = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/parser/struct-literal-in-if.rs b/src/test/ui/parser/struct-literal-in-if.rs
new file mode 100644
index 000000000..2ce2c8f18
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-if.rs
@@ -0,0 +1,17 @@
+struct Foo {
+ x: isize,
+}
+
+impl Foo {
+ fn hi(&self) -> bool {
+ true
+ }
+}
+
+fn main() {
+ if Foo { //~ ERROR struct literals are not allowed here
+ x: 3
+ }.hi() {
+ println!("yo");
+ }
+}
diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr
new file mode 100644
index 000000000..b5a9864bb
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-if.stderr
@@ -0,0 +1,18 @@
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-in-if.rs:12:8
+ |
+LL | if Foo {
+ | ________^
+LL | | x: 3
+LL | | }.hi() {
+ | |_____^
+ |
+help: surround the struct literal with parentheses
+ |
+LL ~ if (Foo {
+LL | x: 3
+LL ~ }).hi() {
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/struct-literal-in-match-discriminant.rs b/src/test/ui/parser/struct-literal-in-match-discriminant.rs
new file mode 100644
index 000000000..ce132df5a
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-match-discriminant.rs
@@ -0,0 +1,13 @@
+struct Foo {
+ x: isize,
+}
+
+fn main() {
+ match Foo { //~ ERROR struct literals are not allowed here
+ x: 3
+ } {
+ Foo {
+ x: x
+ } => {}
+ }
+}
diff --git a/src/test/ui/parser/struct-literal-in-match-discriminant.stderr b/src/test/ui/parser/struct-literal-in-match-discriminant.stderr
new file mode 100644
index 000000000..692b4d735
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-match-discriminant.stderr
@@ -0,0 +1,18 @@
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-in-match-discriminant.rs:6:11
+ |
+LL | match Foo {
+ | ___________^
+LL | | x: 3
+LL | | } {
+ | |_____^
+ |
+help: surround the struct literal with parentheses
+ |
+LL ~ match (Foo {
+LL | x: 3
+LL ~ }) {
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/struct-literal-in-match-guard.rs b/src/test/ui/parser/struct-literal-in-match-guard.rs
new file mode 100644
index 000000000..bf0551b5c
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-match-guard.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+// Unlike `if` condition, `match` guards accept struct literals.
+// This is detected in <https://github.com/rust-lang/rust/pull/74566#issuecomment-663613705>.
+
+#[derive(PartialEq)]
+struct Foo {
+ x: isize,
+}
+
+fn foo(f: Foo) {
+ match () {
+ () if f == Foo { x: 42 } => {}
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/struct-literal-in-while.rs b/src/test/ui/parser/struct-literal-in-while.rs
new file mode 100644
index 000000000..5000ce85b
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-while.rs
@@ -0,0 +1,17 @@
+struct Foo {
+ x: isize,
+}
+
+impl Foo {
+ fn hi(&self) -> bool {
+ true
+ }
+}
+
+fn main() {
+ while Foo { //~ ERROR struct literals are not allowed here
+ x: 3
+ }.hi() {
+ println!("yo");
+ }
+}
diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr
new file mode 100644
index 000000000..17e9277e0
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-in-while.stderr
@@ -0,0 +1,18 @@
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-in-while.rs:12:11
+ |
+LL | while Foo {
+ | ___________^
+LL | | x: 3
+LL | | }.hi() {
+ | |_____^
+ |
+help: surround the struct literal with parentheses
+ |
+LL ~ while (Foo {
+LL | x: 3
+LL ~ }).hi() {
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.rs b/src/test/ui/parser/struct-literal-restrictions-in-lamda.rs
new file mode 100644
index 000000000..e185153dc
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.rs
@@ -0,0 +1,17 @@
+struct Foo {
+ x: isize,
+}
+
+impl Foo {
+ fn hi(&self) -> bool {
+ true
+ }
+}
+
+fn main() {
+ while || Foo { //~ ERROR struct literals are not allowed here
+ x: 3 //~^ ERROR mismatched types
+ }.hi() {
+ println!("yo");
+ }
+}
diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr
new file mode 100644
index 000000000..0852c7cb4
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr
@@ -0,0 +1,37 @@
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-restrictions-in-lamda.rs:12:14
+ |
+LL | while || Foo {
+ | ______________^
+LL | | x: 3
+LL | | }.hi() {
+ | |_____^
+ |
+help: surround the struct literal with parentheses
+ |
+LL ~ while || (Foo {
+LL | x: 3
+LL ~ }).hi() {
+ |
+
+error[E0308]: mismatched types
+ --> $DIR/struct-literal-restrictions-in-lamda.rs:12:11
+ |
+LL | while || Foo {
+ | ___________^
+LL | | x: 3
+LL | | }.hi() {
+ | |__________^ expected `bool`, found closure
+ |
+ = note: expected type `bool`
+ found closure `[closure@$DIR/struct-literal-restrictions-in-lamda.rs:12:11: 12:13]`
+help: use parentheses to call this closure
+ |
+LL ~ while (|| Foo {
+LL | x: 3
+LL ~ }.hi())() {
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/struct-literal-variant-in-if.rs b/src/test/ui/parser/struct-literal-variant-in-if.rs
new file mode 100644
index 000000000..4ef8effaf
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-variant-in-if.rs
@@ -0,0 +1,25 @@
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+enum E {
+ V { field: bool },
+ I { field1: bool, field2: usize },
+ J { field: isize },
+ K { field: &'static str},
+}
+fn test_E(x: E) {
+ let field = true;
+ if x == E::V { field } {}
+ //~^ ERROR expected value, found struct variant `E::V`
+ //~| ERROR mismatched types
+ if x == E::I { field1: true, field2: 42 } {}
+ //~^ ERROR struct literals are not allowed here
+ if x == E::V { field: false } {}
+ //~^ ERROR struct literals are not allowed here
+ if x == E::J { field: -42 } {}
+ //~^ ERROR struct literals are not allowed here
+ if x == E::K { field: "" } {}
+ //~^ ERROR struct literals are not allowed here
+ let y: usize = ();
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr
new file mode 100644
index 000000000..4cffbe433
--- /dev/null
+++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr
@@ -0,0 +1,76 @@
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-variant-in-if.rs:13:13
+ |
+LL | if x == E::I { field1: true, field2: 42 } {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: surround the struct literal with parentheses
+ |
+LL | if x == (E::I { field1: true, field2: 42 }) {}
+ | + +
+
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-variant-in-if.rs:15:13
+ |
+LL | if x == E::V { field: false } {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: surround the struct literal with parentheses
+ |
+LL | if x == (E::V { field: false }) {}
+ | + +
+
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-variant-in-if.rs:17:13
+ |
+LL | if x == E::J { field: -42 } {}
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+help: surround the struct literal with parentheses
+ |
+LL | if x == (E::J { field: -42 }) {}
+ | + +
+
+error: struct literals are not allowed here
+ --> $DIR/struct-literal-variant-in-if.rs:19:13
+ |
+LL | if x == E::K { field: "" } {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: surround the struct literal with parentheses
+ |
+LL | if x == (E::K { field: "" }) {}
+ | + +
+
+error[E0423]: expected value, found struct variant `E::V`
+ --> $DIR/struct-literal-variant-in-if.rs:10:13
+ |
+LL | if x == E::V { field } {}
+ | ^^^^ not a value
+ |
+help: surround the struct literal with parentheses
+ |
+LL | if x == (E::V { field }) {}
+ | + +
+
+error[E0308]: mismatched types
+ --> $DIR/struct-literal-variant-in-if.rs:10:20
+ |
+LL | if x == E::V { field } {}
+ | ---------------^^^^^--
+ | | |
+ | | expected `()`, found `bool`
+ | expected this to be `()`
+
+error[E0308]: mismatched types
+ --> $DIR/struct-literal-variant-in-if.rs:21:20
+ |
+LL | let y: usize = ();
+ | ----- ^^ expected `usize`, found `()`
+ | |
+ | expected due to this
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0308, E0423.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/suggest-semi-in-array.rs b/src/test/ui/parser/suggest-semi-in-array.rs
new file mode 100644
index 000000000..9ce2e59e5
--- /dev/null
+++ b/src/test/ui/parser/suggest-semi-in-array.rs
@@ -0,0 +1,5 @@
+fn main() {
+ let v = [1
+ 2];
+ //~^ ERROR expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `2`
+}
diff --git a/src/test/ui/parser/suggest-semi-in-array.stderr b/src/test/ui/parser/suggest-semi-in-array.stderr
new file mode 100644
index 000000000..d7cd6efae
--- /dev/null
+++ b/src/test/ui/parser/suggest-semi-in-array.stderr
@@ -0,0 +1,10 @@
+error: expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `2`
+ --> $DIR/suggest-semi-in-array.rs:3:5
+ |
+LL | let v = [1
+ | - expected one of `,`, `.`, `;`, `?`, `]`, or an operator
+LL | 2];
+ | ^ unexpected token
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.rs b/src/test/ui/parser/tag-variant-disr-non-nullary.rs
new file mode 100644
index 000000000..a9cfdd549
--- /dev/null
+++ b/src/test/ui/parser/tag-variant-disr-non-nullary.rs
@@ -0,0 +1,12 @@
+enum Color {
+ Red = 0xff0000,
+ //~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants
+ Green = 0x00ff00,
+ Blue = 0x0000ff,
+ Black = 0x000000,
+ White = 0xffffff,
+ Other(usize),
+ Other2(usize, usize),
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr
new file mode 100644
index 000000000..79f044a06
--- /dev/null
+++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr
@@ -0,0 +1,25 @@
+error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
+ --> $DIR/tag-variant-disr-non-nullary.rs:2:11
+ |
+LL | Red = 0xff0000,
+ | ^^^^^^^^ disallowed custom discriminant
+LL |
+LL | Green = 0x00ff00,
+ | ^^^^^^^^ disallowed custom discriminant
+LL | Blue = 0x0000ff,
+ | ^^^^^^^^ disallowed custom discriminant
+LL | Black = 0x000000,
+ | ^^^^^^^^ disallowed custom discriminant
+LL | White = 0xffffff,
+ | ^^^^^^^^ disallowed custom discriminant
+LL | Other(usize),
+ | ------------ tuple variant defined here
+LL | Other2(usize, usize),
+ | -------------------- tuple variant defined here
+ |
+ = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
+ = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.rs b/src/test/ui/parser/trailing-carriage-return-in-string.rs
new file mode 100644
index 000000000..5d3c31944
--- /dev/null
+++ b/src/test/ui/parser/trailing-carriage-return-in-string.rs
@@ -0,0 +1,14 @@
+// Issue #11669
+
+// ignore-tidy-cr
+
+fn main() {
+ // \r\n
+ let ok = "This is \
+ a test";
+ // \r only
+ let bad = "This is \ a test";
+ //~^ ERROR unknown character escape: `\r`
+ //~| HELP this is an isolated carriage return
+
+}
diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr
new file mode 100644
index 000000000..8a44e0270
--- /dev/null
+++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr
@@ -0,0 +1,10 @@
+error: unknown character escape: `\r`
+ --> $DIR/trailing-carriage-return-in-string.rs:10:25
+ |
+LL | let bad = "This is \ a test";
+ | ^ unknown character escape
+ |
+ = help: this is an isolated carriage return; consider checking your editor and version control settings
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/trailing-plus-in-bounds.rs b/src/test/ui/parser/trailing-plus-in-bounds.rs
new file mode 100644
index 000000000..400649bcf
--- /dev/null
+++ b/src/test/ui/parser/trailing-plus-in-bounds.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![allow(bare_trait_objects)]
+
+use std::fmt::Debug;
+
+fn main() {
+ let x: Box<Debug+> = Box::new(3) as Box<Debug+>; // Trailing `+` is OK
+}
diff --git a/src/test/ui/parser/trailing-question-in-macro-type.rs b/src/test/ui/parser/trailing-question-in-macro-type.rs
new file mode 100644
index 000000000..e2a681ddd
--- /dev/null
+++ b/src/test/ui/parser/trailing-question-in-macro-type.rs
@@ -0,0 +1,14 @@
+macro_rules! fn_expr {
+ ($return_type:ty : $body:expr) => {
+ (|| -> $return_type { $body })()
+ };
+ ($body:expr) => {
+ (|| $body)()
+ };
+}
+
+
+fn main() {
+ fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) };
+ //~^ ERROR cannot find value `o` in this scope
+}
diff --git a/src/test/ui/parser/trailing-question-in-macro-type.stderr b/src/test/ui/parser/trailing-question-in-macro-type.stderr
new file mode 100644
index 000000000..c096ae04f
--- /dev/null
+++ b/src/test/ui/parser/trailing-question-in-macro-type.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `o` in this scope
+ --> $DIR/trailing-question-in-macro-type.rs:12:15
+ |
+LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) };
+ | ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/trailing-question-in-type.fixed b/src/test/ui/parser/trailing-question-in-type.fixed
new file mode 100644
index 000000000..6ea24484e
--- /dev/null
+++ b/src/test/ui/parser/trailing-question-in-type.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn foo() -> Option<i32> { //~ ERROR invalid `?` in type
+ let x: Option<i32> = Some(1); //~ ERROR invalid `?` in type
+ x
+}
+
+fn main() {
+ let _: Option<i32> = foo();
+}
diff --git a/src/test/ui/parser/trailing-question-in-type.rs b/src/test/ui/parser/trailing-question-in-type.rs
new file mode 100644
index 000000000..b1c508365
--- /dev/null
+++ b/src/test/ui/parser/trailing-question-in-type.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn foo() -> i32? { //~ ERROR invalid `?` in type
+ let x: i32? = Some(1); //~ ERROR invalid `?` in type
+ x
+}
+
+fn main() {
+ let _: Option<i32> = foo();
+}
diff --git a/src/test/ui/parser/trailing-question-in-type.stderr b/src/test/ui/parser/trailing-question-in-type.stderr
new file mode 100644
index 000000000..a3cd419c0
--- /dev/null
+++ b/src/test/ui/parser/trailing-question-in-type.stderr
@@ -0,0 +1,24 @@
+error: invalid `?` in type
+ --> $DIR/trailing-question-in-type.rs:3:16
+ |
+LL | fn foo() -> i32? {
+ | ^ `?` is only allowed on expressions, not types
+ |
+help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
+ |
+LL | fn foo() -> Option<i32> {
+ | +++++++ ~
+
+error: invalid `?` in type
+ --> $DIR/trailing-question-in-type.rs:4:15
+ |
+LL | let x: i32? = Some(1);
+ | ^ `?` is only allowed on expressions, not types
+ |
+help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
+ |
+LL | let x: Option<i32> = Some(1);
+ | +++++++ ~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/trait-bounds-not-on-impl.rs b/src/test/ui/parser/trait-bounds-not-on-impl.rs
new file mode 100644
index 000000000..02563847e
--- /dev/null
+++ b/src/test/ui/parser/trait-bounds-not-on-impl.rs
@@ -0,0 +1,7 @@
+trait Foo {}
+
+struct Bar;
+
+impl Foo + Owned for Bar {} //~ ERROR expected a trait, found type
+
+fn main() { }
diff --git a/src/test/ui/parser/trait-bounds-not-on-impl.stderr b/src/test/ui/parser/trait-bounds-not-on-impl.stderr
new file mode 100644
index 000000000..8d2d5e3d7
--- /dev/null
+++ b/src/test/ui/parser/trait-bounds-not-on-impl.stderr
@@ -0,0 +1,8 @@
+error: expected a trait, found type
+ --> $DIR/trait-bounds-not-on-impl.rs:5:6
+ |
+LL | impl Foo + Owned for Bar {}
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
new file mode 100644
index 000000000..f2d97b7ba
--- /dev/null
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
@@ -0,0 +1,12 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+fn main() {}
+
+trait X {
+ default const A: u8; //~ ERROR `default` is only allowed on items in trait impls
+ default const B: u8 = 0; //~ ERROR `default` is only allowed on items in trait impls
+ default type D; //~ ERROR `default` is only allowed on items in trait impls
+ default type C: Ord; //~ ERROR `default` is only allowed on items in trait impls
+ default fn f1(); //~ ERROR `default` is only allowed on items in trait impls
+ default fn f2() {} //~ ERROR `default` is only allowed on items in trait impls
+}
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
new file mode 100644
index 000000000..76fa86033
--- /dev/null
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
@@ -0,0 +1,60 @@
+error: `default` is only allowed on items in trait impls
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5
+ |
+LL | default const A: u8;
+ | -------^^^^^^^^^^^^^
+ | |
+ | `default` because of this
+
+error: `default` is only allowed on items in trait impls
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5
+ |
+LL | default const B: u8 = 0;
+ | -------^^^^^^^^^^^^^^^^^
+ | |
+ | `default` because of this
+
+error: `default` is only allowed on items in trait impls
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5
+ |
+LL | default type D;
+ | -------^^^^^^^^
+ | |
+ | `default` because of this
+
+error: `default` is only allowed on items in trait impls
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5
+ |
+LL | default type C: Ord;
+ | -------^^^^^^^^^^^^^
+ | |
+ | `default` because of this
+
+error: `default` is only allowed on items in trait impls
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5
+ |
+LL | default fn f1();
+ | -------^^^^^^^^^
+ | |
+ | `default` because of this
+
+error: `default` is only allowed on items in trait impls
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5
+ |
+LL | default fn f2() {}
+ | -------^^^^^^^^
+ | |
+ | `default` because of this
+
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
diff --git a/src/test/ui/parser/trait-item-with-defaultness-pass.rs b/src/test/ui/parser/trait-item-with-defaultness-pass.rs
new file mode 100644
index 000000000..a6318bd99
--- /dev/null
+++ b/src/test/ui/parser/trait-item-with-defaultness-pass.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+trait X {
+ default const A: u8;
+ default const B: u8 = 0;
+ default type D;
+ default type C: Ord;
+ default fn f1();
+ default fn f2() {}
+}
diff --git a/src/test/ui/parser/trait-object-bad-parens.rs b/src/test/ui/parser/trait-object-bad-parens.rs
new file mode 100644
index 000000000..8e267c744
--- /dev/null
+++ b/src/test/ui/parser/trait-object-bad-parens.rs
@@ -0,0 +1,16 @@
+#![feature(auto_traits)]
+#![feature(negative_impls)]
+#![allow(bare_trait_objects)]
+
+auto trait Auto {}
+
+fn main() {
+ let _: Box<((Auto)) + Auto>;
+ //~^ ERROR expected a path on the left-hand side of `+`, not `((Auto))`
+ let _: Box<(Auto + Auto) + Auto>;
+ //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto + Auto)`
+ let _: Box<(Auto +) + Auto>;
+ //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto)`
+ let _: Box<(dyn Auto) + Auto>;
+ //~^ ERROR expected a path on the left-hand side of `+`, not `(dyn Auto)`
+}
diff --git a/src/test/ui/parser/trait-object-bad-parens.stderr b/src/test/ui/parser/trait-object-bad-parens.stderr
new file mode 100644
index 000000000..74e484eeb
--- /dev/null
+++ b/src/test/ui/parser/trait-object-bad-parens.stderr
@@ -0,0 +1,27 @@
+error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))`
+ --> $DIR/trait-object-bad-parens.rs:8:16
+ |
+LL | let _: Box<((Auto)) + Auto>;
+ | ^^^^^^^^^^^^^^^ expected a path
+
+error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)`
+ --> $DIR/trait-object-bad-parens.rs:10:16
+ |
+LL | let _: Box<(Auto + Auto) + Auto>;
+ | ^^^^^^^^^^^^^^^^^^^^ expected a path
+
+error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)`
+ --> $DIR/trait-object-bad-parens.rs:12:16
+ |
+LL | let _: Box<(Auto +) + Auto>;
+ | ^^^^^^^^^^^^^^^ expected a path
+
+error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)`
+ --> $DIR/trait-object-bad-parens.rs:14:16
+ |
+LL | let _: Box<(dyn Auto) + Auto>;
+ | ^^^^^^^^^^^^^^^^^ expected a path
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0178`.
diff --git a/src/test/ui/parser/trait-object-delimiters.rs b/src/test/ui/parser/trait-object-delimiters.rs
new file mode 100644
index 000000000..b5258eebb
--- /dev/null
+++ b/src/test/ui/parser/trait-object-delimiters.rs
@@ -0,0 +1,17 @@
+// edition:2018
+
+fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
+//~^ ERROR only auto traits can be used as additional traits in a trait object
+
+fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
+
+fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
+//~^ ERROR expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+//~| ERROR at least one trait is required for an object type
+
+fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<`
+
+fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} //~ ERROR invalid `dyn` keyword
+//~^ ERROR only auto traits can be used as additional traits in a trait object
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-object-delimiters.stderr b/src/test/ui/parser/trait-object-delimiters.stderr
new file mode 100644
index 000000000..6eb9c7238
--- /dev/null
+++ b/src/test/ui/parser/trait-object-delimiters.stderr
@@ -0,0 +1,78 @@
+error: ambiguous `+` in a type
+ --> $DIR/trait-object-delimiters.rs:3:13
+ |
+LL | fn foo1(_: &dyn Drop + AsRef<str>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(dyn Drop + AsRef<str>)`
+
+error: incorrect braces around trait bounds
+ --> $DIR/trait-object-delimiters.rs:6:17
+ |
+LL | fn foo2(_: &dyn (Drop + AsRef<str>)) {}
+ | ^ ^
+ |
+help: remove the parentheses
+ |
+LL - fn foo2(_: &dyn (Drop + AsRef<str>)) {}
+LL + fn foo2(_: &dyn Drop + AsRef<str>) {}
+ |
+
+error: expected parameter name, found `{`
+ --> $DIR/trait-object-delimiters.rs:8:17
+ |
+LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
+ | ^ expected parameter name
+
+error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+ --> $DIR/trait-object-delimiters.rs:8:17
+ |
+LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
+ | -^ expected one of 9 possible tokens
+ | |
+ | help: missing `,`
+
+error: expected identifier, found `<`
+ --> $DIR/trait-object-delimiters.rs:12:17
+ |
+LL | fn foo4(_: &dyn <Drop + AsRef<str>>) {}
+ | ^ expected identifier
+
+error: invalid `dyn` keyword
+ --> $DIR/trait-object-delimiters.rs:14:25
+ |
+LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
+ | ^^^ help: remove this keyword
+ |
+ = help: `dyn` is only needed at the start of a trait `+`-separated list
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/trait-object-delimiters.rs:3:24
+ |
+LL | fn foo1(_: &dyn Drop + AsRef<str>) {}
+ | ---- ^^^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error[E0224]: at least one trait is required for an object type
+ --> $DIR/trait-object-delimiters.rs:8:13
+ |
+LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
+ | ^^^
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/trait-object-delimiters.rs:14:29
+ |
+LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
+ | ---- ^^^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0224, E0225.
+For more information about an error, try `rustc --explain E0224`.
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.rs b/src/test/ui/parser/trait-object-lifetime-parens.rs
new file mode 100644
index 000000000..f44ebe5ba
--- /dev/null
+++ b/src/test/ui/parser/trait-object-lifetime-parens.rs
@@ -0,0 +1,13 @@
+#![allow(bare_trait_objects)]
+
+trait Trait {}
+
+fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not supported
+
+fn check<'a>() {
+ let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported
+ // FIXME: It'd be great if we could add suggestion to the following case.
+ let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+`
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr
new file mode 100644
index 000000000..9c7a9662c
--- /dev/null
+++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr
@@ -0,0 +1,20 @@
+error: parenthesized lifetime bounds are not supported
+ --> $DIR/trait-object-lifetime-parens.rs:5:21
+ |
+LL | fn f<'a, T: Trait + ('a)>() {}
+ | ^^^^ help: remove the parentheses
+
+error: parenthesized lifetime bounds are not supported
+ --> $DIR/trait-object-lifetime-parens.rs:8:24
+ |
+LL | let _: Box<Trait + ('a)>;
+ | ^^^^ help: remove the parentheses
+
+error: lifetime in trait object type must be followed by `+`
+ --> $DIR/trait-object-lifetime-parens.rs:10:17
+ |
+LL | let _: Box<('a) + Trait>;
+ | ^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/trait-object-polytrait-priority.rs b/src/test/ui/parser/trait-object-polytrait-priority.rs
new file mode 100644
index 000000000..63425f3e2
--- /dev/null
+++ b/src/test/ui/parser/trait-object-polytrait-priority.rs
@@ -0,0 +1,10 @@
+#![allow(bare_trait_objects)]
+
+trait Trait<'a> {}
+
+fn main() {
+ let _: &for<'a> Trait<'a> + 'static;
+ //~^ ERROR expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
+ //~| HELP try adding parentheses
+ //~| SUGGESTION &(for<'a> Trait<'a> + 'static)
+}
diff --git a/src/test/ui/parser/trait-object-polytrait-priority.stderr b/src/test/ui/parser/trait-object-polytrait-priority.stderr
new file mode 100644
index 000000000..a6add6079
--- /dev/null
+++ b/src/test/ui/parser/trait-object-polytrait-priority.stderr
@@ -0,0 +1,9 @@
+error[E0178]: expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
+ --> $DIR/trait-object-polytrait-priority.rs:6:12
+ |
+LL | let _: &for<'a> Trait<'a> + 'static;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try adding parentheses: `&(for<'a> Trait<'a> + 'static)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0178`.
diff --git a/src/test/ui/parser/trait-object-trait-parens.rs b/src/test/ui/parser/trait-object-trait-parens.rs
new file mode 100644
index 000000000..438034bc3
--- /dev/null
+++ b/src/test/ui/parser/trait-object-trait-parens.rs
@@ -0,0 +1,23 @@
+trait Trait<'a> {}
+
+trait Obj {}
+
+fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {}
+
+fn main() {
+ let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+ //~^ ERROR `?Trait` is not permitted in trait object types
+ //~| ERROR only auto traits can be used as additional traits
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
+ //~^ ERROR `?Trait` is not permitted in trait object types
+ //~| ERROR only auto traits can be used as additional traits
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+ let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
+ //~^ ERROR `?Trait` is not permitted in trait object types
+ //~| ERROR only auto traits can be used as additional traits
+ //~| WARN trait objects without an explicit `dyn` are deprecated
+ //~| WARN this is accepted in the current edition
+}
diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr
new file mode 100644
index 000000000..7ee965bd2
--- /dev/null
+++ b/src/test/ui/parser/trait-object-trait-parens.stderr
@@ -0,0 +1,97 @@
+error: `?Trait` is not permitted in trait object types
+ --> $DIR/trait-object-trait-parens.rs:8:24
+ |
+LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+ | ^^^^^^^^
+
+error: `?Trait` is not permitted in trait object types
+ --> $DIR/trait-object-trait-parens.rs:13:16
+ |
+LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
+ | ^^^^^^
+
+error: `?Trait` is not permitted in trait object types
+ --> $DIR/trait-object-trait-parens.rs:18:44
+ |
+LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
+ | ^^^^^^^^
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/trait-object-trait-parens.rs:8:16
+ |
+LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(bare_trait_objects)]` on by default
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL - let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+LL + let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+ |
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/trait-object-trait-parens.rs:8:35
+ |
+LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
+ | ----- ^^^^^^^^^^^^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Obj + for<'a> Trait<'a> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/trait-object-trait-parens.rs:13:16
+ |
+LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL - let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
+LL + let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
+ |
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/trait-object-trait-parens.rs:13:47
+ |
+LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
+ | ------------------- ^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/trait-object-trait-parens.rs:18:16
+ |
+LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+ |
+LL - let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
+LL + let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
+ |
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/trait-object-trait-parens.rs:18:36
+ |
+LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
+ | ----------------- ^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error: aborting due to 6 previous errors; 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0225`.
diff --git a/src/test/ui/parser/trait-plusequal-splitting.rs b/src/test/ui/parser/trait-plusequal-splitting.rs
new file mode 100644
index 000000000..6ca677450
--- /dev/null
+++ b/src/test/ui/parser/trait-plusequal-splitting.rs
@@ -0,0 +1,8 @@
+// Fixes issue where `+` in generics weren't parsed if they were part of a `+=`.
+
+// check-pass
+
+struct Whitespace<T: Clone + = ()> { t: T }
+struct TokenSplit<T: Clone += ()> { t: T }
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-const.rs b/src/test/ui/parser/trait-pub-assoc-const.rs
new file mode 100644
index 000000000..219ffa309
--- /dev/null
+++ b/src/test/ui/parser/trait-pub-assoc-const.rs
@@ -0,0 +1,6 @@
+trait Foo {
+ pub const Foo: u32;
+ //~^ ERROR unnecessary visibility qualifier
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-const.stderr b/src/test/ui/parser/trait-pub-assoc-const.stderr
new file mode 100644
index 000000000..efd09a036
--- /dev/null
+++ b/src/test/ui/parser/trait-pub-assoc-const.stderr
@@ -0,0 +1,9 @@
+error[E0449]: unnecessary visibility qualifier
+ --> $DIR/trait-pub-assoc-const.rs:2:5
+ |
+LL | pub const Foo: u32;
+ | ^^^ `pub` not permitted here because it's implied
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0449`.
diff --git a/src/test/ui/parser/trait-pub-assoc-ty.rs b/src/test/ui/parser/trait-pub-assoc-ty.rs
new file mode 100644
index 000000000..a78dfbdcd
--- /dev/null
+++ b/src/test/ui/parser/trait-pub-assoc-ty.rs
@@ -0,0 +1,6 @@
+trait Foo {
+ pub type Foo;
+ //~^ ERROR unnecessary visibility qualifier
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-ty.stderr b/src/test/ui/parser/trait-pub-assoc-ty.stderr
new file mode 100644
index 000000000..e76373f5c
--- /dev/null
+++ b/src/test/ui/parser/trait-pub-assoc-ty.stderr
@@ -0,0 +1,9 @@
+error[E0449]: unnecessary visibility qualifier
+ --> $DIR/trait-pub-assoc-ty.rs:2:5
+ |
+LL | pub type Foo;
+ | ^^^ `pub` not permitted here because it's implied
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0449`.
diff --git a/src/test/ui/parser/trait-pub-method.rs b/src/test/ui/parser/trait-pub-method.rs
new file mode 100644
index 000000000..1f6ee028a
--- /dev/null
+++ b/src/test/ui/parser/trait-pub-method.rs
@@ -0,0 +1,6 @@
+trait Foo {
+ pub fn foo();
+ //~^ ERROR unnecessary visibility qualifier
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-pub-method.stderr b/src/test/ui/parser/trait-pub-method.stderr
new file mode 100644
index 000000000..0e3fe027c
--- /dev/null
+++ b/src/test/ui/parser/trait-pub-method.stderr
@@ -0,0 +1,9 @@
+error[E0449]: unnecessary visibility qualifier
+ --> $DIR/trait-pub-method.rs:2:5
+ |
+LL | pub fn foo();
+ | ^^^ `pub` not permitted here because it's implied
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0449`.
diff --git a/src/test/ui/parser/type-alias-where-fixable.fixed b/src/test/ui/parser/type-alias-where-fixable.fixed
new file mode 100644
index 000000000..41dd10676
--- /dev/null
+++ b/src/test/ui/parser/type-alias-where-fixable.fixed
@@ -0,0 +1,30 @@
+// check-pass
+// run-rustfix
+
+#![feature(generic_associated_types)]
+
+trait Trait {
+ // Fine.
+ type Assoc where u32: Copy;
+ // Fine.
+ type Assoc2 where u32: Copy, i32: Copy;
+}
+
+impl Trait for u32 {
+ // Not fine, suggests moving.
+ type Assoc = () where u32: Copy;
+ //~^ WARNING where clause not allowed here
+ // Not fine, suggests moving `u32: Copy`
+ type Assoc2 = () where i32: Copy, u32: Copy;
+ //~^ WARNING where clause not allowed here
+}
+
+impl Trait for i32 {
+ // Fine.
+ type Assoc = () where u32: Copy;
+ // Not fine, suggests moving both.
+ type Assoc2 = () where u32: Copy, i32: Copy;
+ //~^ WARNING where clause not allowed here
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/type-alias-where-fixable.rs b/src/test/ui/parser/type-alias-where-fixable.rs
new file mode 100644
index 000000000..562a530a7
--- /dev/null
+++ b/src/test/ui/parser/type-alias-where-fixable.rs
@@ -0,0 +1,30 @@
+// check-pass
+// run-rustfix
+
+#![feature(generic_associated_types)]
+
+trait Trait {
+ // Fine.
+ type Assoc where u32: Copy;
+ // Fine.
+ type Assoc2 where u32: Copy, i32: Copy;
+}
+
+impl Trait for u32 {
+ // Not fine, suggests moving.
+ type Assoc where u32: Copy = ();
+ //~^ WARNING where clause not allowed here
+ // Not fine, suggests moving `u32: Copy`
+ type Assoc2 where u32: Copy = () where i32: Copy;
+ //~^ WARNING where clause not allowed here
+}
+
+impl Trait for i32 {
+ // Fine.
+ type Assoc = () where u32: Copy;
+ // Not fine, suggests moving both.
+ type Assoc2 where u32: Copy, i32: Copy = ();
+ //~^ WARNING where clause not allowed here
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/type-alias-where-fixable.stderr b/src/test/ui/parser/type-alias-where-fixable.stderr
new file mode 100644
index 000000000..abfeb62fc
--- /dev/null
+++ b/src/test/ui/parser/type-alias-where-fixable.stderr
@@ -0,0 +1,42 @@
+warning: where clause not allowed here
+ --> $DIR/type-alias-where-fixable.rs:15:16
+ |
+LL | type Assoc where u32: Copy = ();
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(deprecated_where_clause_location)]` on by default
+ = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+help: move it to the end of the type declaration
+ |
+LL - type Assoc where u32: Copy = ();
+LL + type Assoc = () where u32: Copy;
+ |
+
+warning: where clause not allowed here
+ --> $DIR/type-alias-where-fixable.rs:18:17
+ |
+LL | type Assoc2 where u32: Copy = () where i32: Copy;
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+help: move it to the end of the type declaration
+ |
+LL - type Assoc2 where u32: Copy = () where i32: Copy;
+LL + type Assoc2 = () where i32: Copy, u32: Copy;
+ |
+
+warning: where clause not allowed here
+ --> $DIR/type-alias-where-fixable.rs:26:17
+ |
+LL | type Assoc2 where u32: Copy, i32: Copy = ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+help: move it to the end of the type declaration
+ |
+LL - type Assoc2 where u32: Copy, i32: Copy = ();
+LL + type Assoc2 = () where u32: Copy, i32: Copy;
+ |
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/parser/type-alias-where.rs b/src/test/ui/parser/type-alias-where.rs
new file mode 100644
index 000000000..f6e7dfb7b
--- /dev/null
+++ b/src/test/ui/parser/type-alias-where.rs
@@ -0,0 +1,13 @@
+// check-fail
+
+#![feature(generic_associated_types)]
+
+// Fine, but lints as unused
+type Foo where u32: Copy = ();
+// Not fine.
+type Bar = () where u32: Copy;
+//~^ ERROR where clauses are not allowed
+type Baz = () where;
+//~^ ERROR where clauses are not allowed
+
+fn main() {}
diff --git a/src/test/ui/parser/type-alias-where.stderr b/src/test/ui/parser/type-alias-where.stderr
new file mode 100644
index 000000000..8789d2665
--- /dev/null
+++ b/src/test/ui/parser/type-alias-where.stderr
@@ -0,0 +1,18 @@
+error: where clauses are not allowed after the type for type aliases
+ --> $DIR/type-alias-where.rs:8:15
+ |
+LL | type Bar = () where u32: Copy;
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+
+error: where clauses are not allowed after the type for type aliases
+ --> $DIR/type-alias-where.rs:10:15
+ |
+LL | type Baz = () where;
+ | ^^^^^
+ |
+ = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.rs b/src/test/ui/parser/type-parameters-in-field-exprs.rs
new file mode 100644
index 000000000..4cd77ebbd
--- /dev/null
+++ b/src/test/ui/parser/type-parameters-in-field-exprs.rs
@@ -0,0 +1,17 @@
+struct Foo {
+ x: isize,
+ y: isize,
+}
+
+fn main() {
+ let f = Foo {
+ x: 1,
+ y: 2,
+ };
+ f.x::<isize>;
+ //~^ ERROR field expressions cannot have generic arguments
+ f.x::<>;
+ //~^ ERROR field expressions cannot have generic arguments
+ f.x::();
+ //~^ ERROR field expressions cannot have generic arguments
+}
diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
new file mode 100644
index 000000000..ce7364d35
--- /dev/null
+++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
@@ -0,0 +1,20 @@
+error: field expressions cannot have generic arguments
+ --> $DIR/type-parameters-in-field-exprs.rs:11:10
+ |
+LL | f.x::<isize>;
+ | ^^^^^^^
+
+error: field expressions cannot have generic arguments
+ --> $DIR/type-parameters-in-field-exprs.rs:13:10
+ |
+LL | f.x::<>;
+ | ^^
+
+error: field expressions cannot have generic arguments
+ --> $DIR/type-parameters-in-field-exprs.rs:15:7
+ |
+LL | f.x::();
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/unbalanced-doublequote.rs b/src/test/ui/parser/unbalanced-doublequote.rs
new file mode 100644
index 000000000..f21316205
--- /dev/null
+++ b/src/test/ui/parser/unbalanced-doublequote.rs
@@ -0,0 +1,6 @@
+// error-pattern: unterminated double quote string
+
+
+fn main() {
+ "
+}
diff --git a/src/test/ui/parser/unbalanced-doublequote.stderr b/src/test/ui/parser/unbalanced-doublequote.stderr
new file mode 100644
index 000000000..94b300a7b
--- /dev/null
+++ b/src/test/ui/parser/unbalanced-doublequote.stderr
@@ -0,0 +1,10 @@
+error[E0765]: unterminated double quote string
+ --> $DIR/unbalanced-doublequote.rs:5:5
+ |
+LL | / "
+LL | | }
+ | |__^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0765`.
diff --git a/src/test/ui/parser/unclosed-braces.rs b/src/test/ui/parser/unclosed-braces.rs
new file mode 100644
index 000000000..ed94fff38
--- /dev/null
+++ b/src/test/ui/parser/unclosed-braces.rs
@@ -0,0 +1,22 @@
+struct S {
+ x: [usize; 3],
+}
+
+fn foo() {
+ {
+ {
+ println!("hi");
+ }
+ }
+}
+
+fn main() {
+//~^ NOTE unclosed delimiter
+ {
+ {
+ //~^ NOTE this delimiter might not be properly closed...
+ foo();
+ }
+ //~^ NOTE ...as it matches this but it has different indentation
+}
+//~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/unclosed-braces.stderr b/src/test/ui/parser/unclosed-braces.stderr
new file mode 100644
index 000000000..cbc5f8de4
--- /dev/null
+++ b/src/test/ui/parser/unclosed-braces.stderr
@@ -0,0 +1,17 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/unclosed-braces.rs:22:52
+ |
+LL | fn main() {
+ | - unclosed delimiter
+...
+LL | {
+ | - this delimiter might not be properly closed...
+...
+LL | }
+ | - ...as it matches this but it has different indentation
+...
+LL |
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.rs b/src/test/ui/parser/unclosed-delimiter-in-dep.rs
new file mode 100644
index 000000000..6db1b66e9
--- /dev/null
+++ b/src/test/ui/parser/unclosed-delimiter-in-dep.rs
@@ -0,0 +1,6 @@
+mod unclosed_delim_mod;
+
+fn main() {
+ let _: usize = unclosed_delim_mod::new();
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
new file mode 100644
index 000000000..1366ef1bb
--- /dev/null
+++ b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
@@ -0,0 +1,25 @@
+error: mismatched closing delimiter: `}`
+ --> $DIR/unclosed_delim_mod.rs:5:7
+ |
+LL | pub fn new() -> Result<Value, ()> {
+ | - closing delimiter possibly meant for this
+LL | Ok(Value {
+ | ^ unclosed delimiter
+LL | }
+LL | }
+ | ^ mismatched closing delimiter
+
+error[E0308]: mismatched types
+ --> $DIR/unclosed-delimiter-in-dep.rs:4:20
+ |
+LL | let _: usize = unclosed_delim_mod::new();
+ | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found enum `Result`
+ | |
+ | expected due to this
+ |
+ = note: expected type `usize`
+ found enum `Result<Value, ()>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/unclosed_delim_mod.rs b/src/test/ui/parser/unclosed_delim_mod.rs
new file mode 100644
index 000000000..d977d2c03
--- /dev/null
+++ b/src/test/ui/parser/unclosed_delim_mod.rs
@@ -0,0 +1,8 @@
+fn main() {}
+
+pub struct Value {}
+pub fn new() -> Result<Value, ()> {
+ Ok(Value {
+ }
+}
+//~^ ERROR mismatched closing delimiter
diff --git a/src/test/ui/parser/unclosed_delim_mod.stderr b/src/test/ui/parser/unclosed_delim_mod.stderr
new file mode 100644
index 000000000..a46d020b9
--- /dev/null
+++ b/src/test/ui/parser/unclosed_delim_mod.stderr
@@ -0,0 +1,13 @@
+error: mismatched closing delimiter: `}`
+ --> $DIR/unclosed_delim_mod.rs:5:7
+ |
+LL | pub fn new() -> Result<Value, ()> {
+ | - closing delimiter possibly meant for this
+LL | Ok(Value {
+ | ^ unclosed delimiter
+LL | }
+LL | }
+ | ^ mismatched closing delimiter
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/underscore-suffix-for-float.rs b/src/test/ui/parser/underscore-suffix-for-float.rs
new file mode 100644
index 000000000..c9b7eced0
--- /dev/null
+++ b/src/test/ui/parser/underscore-suffix-for-float.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let a = 42._; //~ ERROR expected identifier, found reserved identifier `_`
+ //~| ERROR `{integer}` is a primitive type and therefore doesn't have fields
+}
diff --git a/src/test/ui/parser/underscore-suffix-for-float.stderr b/src/test/ui/parser/underscore-suffix-for-float.stderr
new file mode 100644
index 000000000..a5f3b6551
--- /dev/null
+++ b/src/test/ui/parser/underscore-suffix-for-float.stderr
@@ -0,0 +1,15 @@
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore-suffix-for-float.rs:2:16
+ |
+LL | let a = 42._;
+ | ^ expected identifier, found reserved identifier
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+ --> $DIR/underscore-suffix-for-float.rs:2:16
+ |
+LL | let a = 42._;
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0610`.
diff --git a/src/test/ui/parser/underscore-suffix-for-string.rs b/src/test/ui/parser/underscore-suffix-for-string.rs
new file mode 100644
index 000000000..2e0ebe2cf
--- /dev/null
+++ b/src/test/ui/parser/underscore-suffix-for-string.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+fn main() {
+ let _ = "Foo"_;
+ //~^ WARNING underscore literal suffix is not allowed
+ //~| WARNING this was previously accepted
+ //~| NOTE issue #42326
+}
diff --git a/src/test/ui/parser/underscore-suffix-for-string.stderr b/src/test/ui/parser/underscore-suffix-for-string.stderr
new file mode 100644
index 000000000..00c7657f1
--- /dev/null
+++ b/src/test/ui/parser/underscore-suffix-for-string.stderr
@@ -0,0 +1,11 @@
+warning: underscore literal suffix is not allowed
+ --> $DIR/underscore-suffix-for-string.rs:4:18
+ |
+LL | let _ = "Foo"_;
+ | ^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: see issue #42326 <https://github.com/rust-lang/rust/issues/42326> for more information
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/parser/underscore_item_not_const.rs b/src/test/ui/parser/underscore_item_not_const.rs
new file mode 100644
index 000000000..c01ac4752
--- /dev/null
+++ b/src/test/ui/parser/underscore_item_not_const.rs
@@ -0,0 +1,16 @@
+// Test that various non-const items do not syntactically permit `_` as a name.
+
+static _: () = (); //~ ERROR expected identifier, found reserved identifier `_`
+struct _(); //~ ERROR expected identifier, found reserved identifier `_`
+enum _ {} //~ ERROR expected identifier, found reserved identifier `_`
+fn _() {} //~ ERROR expected identifier, found reserved identifier `_`
+mod _ {} //~ ERROR expected identifier, found reserved identifier `_`
+type _ = (); //~ ERROR expected identifier, found reserved identifier `_`
+use _; //~ ERROR expected identifier, found reserved identifier `_`
+use _ as g; //~ ERROR expected identifier, found reserved identifier `_`
+trait _ {} //~ ERROR expected identifier, found reserved identifier `_`
+trait _ = Copy; //~ ERROR expected identifier, found reserved identifier `_`
+macro_rules! _ { () => {} } //~ ERROR expected identifier, found reserved identifier `_`
+union _ { f: u8 } //~ ERROR expected one of `!` or `::`, found reserved identifier `_`
+
+fn main() {}
diff --git a/src/test/ui/parser/underscore_item_not_const.stderr b/src/test/ui/parser/underscore_item_not_const.stderr
new file mode 100644
index 000000000..0bc7642dd
--- /dev/null
+++ b/src/test/ui/parser/underscore_item_not_const.stderr
@@ -0,0 +1,74 @@
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:3:8
+ |
+LL | static _: () = ();
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:4:8
+ |
+LL | struct _();
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:5:6
+ |
+LL | enum _ {}
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:6:4
+ |
+LL | fn _() {}
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:7:5
+ |
+LL | mod _ {}
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:8:6
+ |
+LL | type _ = ();
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:9:5
+ |
+LL | use _;
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:10:5
+ |
+LL | use _ as g;
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:11:7
+ |
+LL | trait _ {}
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:12:7
+ |
+LL | trait _ = Copy;
+ | ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:13:14
+ |
+LL | macro_rules! _ { () => {} }
+ | ^ expected identifier, found reserved identifier
+
+error: expected one of `!` or `::`, found reserved identifier `_`
+ --> $DIR/underscore_item_not_const.rs:14:7
+ |
+LL | union _ { f: u8 }
+ | ^ expected one of `!` or `::`
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/parser/unicode-character-literal.fixed b/src/test/ui/parser/unicode-character-literal.fixed
new file mode 100644
index 000000000..26ef5ffa1
--- /dev/null
+++ b/src/test/ui/parser/unicode-character-literal.fixed
@@ -0,0 +1,21 @@
+// Regression test for #88684: Improve diagnostics for combining marks
+// in character literals.
+
+// run-rustfix
+
+fn main() {
+ let _spade = "♠️";
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}`
+ //~| HELP: if you meant to write a `str` literal, use double quotes
+
+ let _s = "ṩ̂̊";
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}`
+ //~| HELP: if you meant to write a `str` literal, use double quotes
+
+ let _a = 'Å';
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: this `A` is followed by the combining mark `\u{30a}`
+ //~| HELP: consider using the normalized form `\u{c5}` of this character
+}
diff --git a/src/test/ui/parser/unicode-character-literal.rs b/src/test/ui/parser/unicode-character-literal.rs
new file mode 100644
index 000000000..d331522c0
--- /dev/null
+++ b/src/test/ui/parser/unicode-character-literal.rs
@@ -0,0 +1,21 @@
+// Regression test for #88684: Improve diagnostics for combining marks
+// in character literals.
+
+// run-rustfix
+
+fn main() {
+ let _spade = '♠️';
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: this `♠` is followed by the combining mark `\u{fe0f}`
+ //~| HELP: if you meant to write a `str` literal, use double quotes
+
+ let _s = 'ṩ̂̊';
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}`
+ //~| HELP: if you meant to write a `str` literal, use double quotes
+
+ let _a = 'Å';
+ //~^ ERROR: character literal may only contain one codepoint
+ //~| NOTE: this `A` is followed by the combining mark `\u{30a}`
+ //~| HELP: consider using the normalized form `\u{c5}` of this character
+}
diff --git a/src/test/ui/parser/unicode-character-literal.stderr b/src/test/ui/parser/unicode-character-literal.stderr
new file mode 100644
index 000000000..5cd3bd0fe
--- /dev/null
+++ b/src/test/ui/parser/unicode-character-literal.stderr
@@ -0,0 +1,48 @@
+error: character literal may only contain one codepoint
+ --> $DIR/unicode-character-literal.rs:7:18
+ |
+LL | let _spade = '♠️';
+ | ^^^
+ |
+note: this `♠` is followed by the combining mark `\u{fe0f}`
+ --> $DIR/unicode-character-literal.rs:7:19
+ |
+LL | let _spade = '♠️';
+ | ^
+help: if you meant to write a `str` literal, use double quotes
+ |
+LL | let _spade = "♠️";
+ | ~~~
+
+error: character literal may only contain one codepoint
+ --> $DIR/unicode-character-literal.rs:12:14
+ |
+LL | let _s = 'ṩ̂̊';
+ | ^^^
+ |
+note: this `s` is followed by the combining marks `\u{323}\u{307}\u{302}\u{30a}`
+ --> $DIR/unicode-character-literal.rs:12:15
+ |
+LL | let _s = 'ṩ̂̊';
+ | ^
+help: if you meant to write a `str` literal, use double quotes
+ |
+LL | let _s = "ṩ̂̊";
+ | ~~~
+
+error: character literal may only contain one codepoint
+ --> $DIR/unicode-character-literal.rs:17:14
+ |
+LL | let _a = 'Å';
+ | ^-^
+ | |
+ | help: consider using the normalized form `\u{c5}` of this character: `Å`
+ |
+note: this `A` is followed by the combining mark `\u{30a}`
+ --> $DIR/unicode-character-literal.rs:17:15
+ |
+LL | let _a = 'Å';
+ | ^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/unicode-chars.rs b/src/test/ui/parser/unicode-chars.rs
new file mode 100644
index 000000000..89ae85ec9
--- /dev/null
+++ b/src/test/ui/parser/unicode-chars.rs
@@ -0,0 +1,5 @@
+fn main() {
+ let y = 0;
+ //~^ ERROR unknown start of token: \u{37e}
+ //~^^ HELP Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
+}
diff --git a/src/test/ui/parser/unicode-chars.stderr b/src/test/ui/parser/unicode-chars.stderr
new file mode 100644
index 000000000..0cfe9240e
--- /dev/null
+++ b/src/test/ui/parser/unicode-chars.stderr
@@ -0,0 +1,13 @@
+error: unknown start of token: \u{37e}
+ --> $DIR/unicode-chars.rs:2:14
+ |
+LL | let y = 0;
+ | ^
+ |
+help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
+ |
+LL | let y = 0;
+ | ~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unicode-control-codepoints.rs b/src/test/ui/parser/unicode-control-codepoints.rs
new file mode 100644
index 000000000..5af0b585a
--- /dev/null
+++ b/src/test/ui/parser/unicode-control-codepoints.rs
@@ -0,0 +1,39 @@
+fn main() {
+ // if access_level != "us‫e‪r" { // Check if admin
+ //~^ ERROR unicode codepoint changing visible direction of text present in comment
+ println!("us\u{202B}e\u{202A}r");
+ println!("{:?}", r#"us\u{202B}e\u{202A}r"#);
+ println!("{:?}", b"us\u{202B}e\u{202A}r");
+ //~^ ERROR unicode escape in byte string
+ //~| ERROR unicode escape in byte string
+ println!("{:?}", br##"us\u{202B}e\u{202A}r"##);
+
+ println!("{:?}", "/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only ");
+ //~^ ERROR unicode codepoint changing visible direction of text present in literal
+
+ println!("{:?}", r##"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only "##);
+ //~^ ERROR unicode codepoint changing visible direction of text present in literal
+ println!("{:?}", b"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only ");
+ //~^ ERROR non-ASCII character in byte constant
+ //~| ERROR non-ASCII character in byte constant
+ //~| ERROR non-ASCII character in byte constant
+ //~| ERROR non-ASCII character in byte constant
+ println!("{:?}", br##"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only "##);
+ //~^ ERROR raw byte string must be ASCII
+ //~| ERROR raw byte string must be ASCII
+ //~| ERROR raw byte string must be ASCII
+ //~| ERROR raw byte string must be ASCII
+ println!("{:?}", '‮');
+ //~^ ERROR unicode codepoint changing visible direction of text present in literal
+}
+
+//"/*‮ } ⁦if isAdmin⁩ ⁦ begin admins only */"
+//~^ ERROR unicode codepoint changing visible direction of text present in comment
+
+/** '‮'); */fn foo() {}
+//~^ ERROR unicode codepoint changing visible direction of text present in doc comment
+
+/**
+ *
+ * '‮'); */fn bar() {}
+//~^^^ ERROR unicode codepoint changing visible direction of text present in doc comment
diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr
new file mode 100644
index 000000000..71509fe41
--- /dev/null
+++ b/src/test/ui/parser/unicode-control-codepoints.stderr
@@ -0,0 +1,192 @@
+error: unicode escape in byte string
+ --> $DIR/unicode-control-codepoints.rs:6:26
+ |
+LL | println!("{:?}", b"us\u{202B}e\u{202A}r");
+ | ^^^^^^^^ unicode escape in byte string
+ |
+ = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: unicode escape in byte string
+ --> $DIR/unicode-control-codepoints.rs:6:35
+ |
+LL | println!("{:?}", b"us\u{202B}e\u{202A}r");
+ | ^^^^^^^^ unicode escape in byte string
+ |
+ = help: unicode escape sequences cannot be used as a byte or in a byte string
+
+error: non-ASCII character in byte constant
+ --> $DIR/unicode-control-codepoints.rs:16:26
+ |
+LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
+ | ^ byte constant must be ASCII but is '\u{202e}'
+ |
+help: if you meant to use the UTF-8 encoding of '\u{202e}', use \xHH escapes
+ |
+LL | println!("{:?}", b"/*\xE2\x80\xAE } if isAdmin begin admins only ");
+ | ~~~~~~~~~~~~
+
+error: non-ASCII character in byte constant
+ --> $DIR/unicode-control-codepoints.rs:16:30
+ |
+LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
+ | ^ byte constant must be ASCII but is '\u{2066}'
+ |
+help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes
+ |
+LL | println!("{:?}", b"/* } \xE2\x81\xA6if isAdmin begin admins only ");
+ | ~~~~~~~~~~~~
+
+error: non-ASCII character in byte constant
+ --> $DIR/unicode-control-codepoints.rs:16:41
+ |
+LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
+ | ^ byte constant must be ASCII but is '\u{2069}'
+ |
+help: if you meant to use the UTF-8 encoding of '\u{2069}', use \xHH escapes
+ |
+LL | println!("{:?}", b"/* } if isAdmin\xE2\x81\xA9 begin admins only ");
+ | ~~~~~~~~~~~~
+
+error: non-ASCII character in byte constant
+ --> $DIR/unicode-control-codepoints.rs:16:43
+ |
+LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
+ | ^ byte constant must be ASCII but is '\u{2066}'
+ |
+help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes
+ |
+LL | println!("{:?}", b"/* } if isAdmin \xE2\x81\xA6 begin admins only ");
+ | ~~~~~~~~~~~~
+
+error: raw byte string must be ASCII
+ --> $DIR/unicode-control-codepoints.rs:21:29
+ |
+LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
+ | ^ must be ASCII but is '\u{202e}'
+
+error: raw byte string must be ASCII
+ --> $DIR/unicode-control-codepoints.rs:21:33
+ |
+LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
+ | ^ must be ASCII but is '\u{2066}'
+
+error: raw byte string must be ASCII
+ --> $DIR/unicode-control-codepoints.rs:21:44
+ |
+LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
+ | ^ must be ASCII but is '\u{2069}'
+
+error: raw byte string must be ASCII
+ --> $DIR/unicode-control-codepoints.rs:21:46
+ |
+LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
+ | ^ must be ASCII but is '\u{2066}'
+
+error: unicode codepoint changing visible direction of text present in comment
+ --> $DIR/unicode-control-codepoints.rs:2:5
+ |
+LL | // if access_level != "user" { // Check if admin
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^
+ | | ||
+ | | |'\u{202a}'
+ | | '\u{202b}'
+ | this comment contains invisible unicode text flow control codepoints
+ |
+ = note: `#[deny(text_direction_codepoint_in_comment)]` on by default
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = help: if their presence wasn't intentional, you can remove them
+
+error: unicode codepoint changing visible direction of text present in comment
+ --> $DIR/unicode-control-codepoints.rs:30:1
+ |
+LL | //"/* } if isAdmin begin admins only */"
+ | ^^^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^
+ | | | | ||
+ | | | | |'\u{2066}'
+ | | | | '\u{2069}'
+ | | | '\u{2066}'
+ | | '\u{202e}'
+ | this comment contains invisible unicode text flow control codepoints
+ |
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = help: if their presence wasn't intentional, you can remove them
+
+error: unicode codepoint changing visible direction of text present in literal
+ --> $DIR/unicode-control-codepoints.rs:11:22
+ |
+LL | println!("{:?}", "/* } if isAdmin begin admins only ");
+ | ^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^
+ | | | | ||
+ | | | | |'\u{2066}'
+ | | | | '\u{2069}'
+ | | | '\u{2066}'
+ | | '\u{202e}'
+ | this literal contains invisible unicode text flow control codepoints
+ |
+ = note: `#[deny(text_direction_codepoint_in_literal)]` on by default
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = help: if their presence wasn't intentional, you can remove them
+help: if you want to keep them but make them visible in your source code, you can escape them
+ |
+LL | println!("{:?}", "/*\u{202e} } \u{2066}if isAdmin\u{2069} \u{2066} begin admins only ");
+ | ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~~~~~
+
+error: unicode codepoint changing visible direction of text present in literal
+ --> $DIR/unicode-control-codepoints.rs:14:22
+ |
+LL | println!("{:?}", r##"/* } if isAdmin begin admins only "##);
+ | ^^^^^^-^^-^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^
+ | | | | ||
+ | | | | |'\u{2066}'
+ | | | | '\u{2069}'
+ | | | '\u{2066}'
+ | | '\u{202e}'
+ | this literal contains invisible unicode text flow control codepoints
+ |
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = help: if their presence wasn't intentional, you can remove them
+help: if you want to keep them but make them visible in your source code, you can escape them
+ |
+LL | println!("{:?}", r##"/*\u{202e} } \u{2066}if isAdmin\u{2069} \u{2066} begin admins only "##);
+ | ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~~~~~
+
+error: unicode codepoint changing visible direction of text present in literal
+ --> $DIR/unicode-control-codepoints.rs:26:22
+ |
+LL | println!("{:?}", '');
+ | ^-
+ | ||
+ | |'\u{202e}'
+ | this literal contains an invisible unicode text flow control codepoint
+ |
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = help: if their presence wasn't intentional, you can remove them
+help: if you want to keep them but make them visible in your source code, you can escape them
+ |
+LL | println!("{:?}", '\u{202e}');
+ | ~~~~~~~~
+
+error: unicode codepoint changing visible direction of text present in doc comment
+ --> $DIR/unicode-control-codepoints.rs:33:1
+ |
+LL | /** ''); */fn foo() {}
+ | ^^^^^^^^^^^^ this doc comment contains an invisible unicode text flow control codepoint
+ |
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = note: if their presence wasn't intentional, you can remove them
+ = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}'
+
+error: unicode codepoint changing visible direction of text present in doc comment
+ --> $DIR/unicode-control-codepoints.rs:36:1
+ |
+LL | / /**
+LL | | *
+LL | | * ''); */fn bar() {}
+ | |___________^ this doc comment contains an invisible unicode text flow control codepoint
+ |
+ = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+ = note: if their presence wasn't intentional, you can remove them
+ = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}'
+
+error: aborting due to 17 previous errors
+
diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs
new file mode 100644
index 000000000..868d2b227
--- /dev/null
+++ b/src/test/ui/parser/unicode-quote-chars.rs
@@ -0,0 +1,8 @@
+fn main() {
+ println!(“hello world”);
+ //~^ ERROR unknown start of token: \u{201c}
+ //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not
+ //~^^^ ERROR unknown start of token: \u{201d}
+ //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
+ //~^^^^^ ERROR expected `,`, found `world`
+}
diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr
new file mode 100644
index 000000000..092abeb53
--- /dev/null
+++ b/src/test/ui/parser/unicode-quote-chars.stderr
@@ -0,0 +1,30 @@
+error: unknown start of token: \u{201c}
+ --> $DIR/unicode-quote-chars.rs:2:14
+ |
+LL | println!(“hello world”);
+ | ^
+ |
+help: Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not
+ |
+LL | println!("hello world");
+ | ~~~~~~~~~~~~~
+
+error: unknown start of token: \u{201d}
+ --> $DIR/unicode-quote-chars.rs:2:26
+ |
+LL | println!(“hello world”);
+ | ^
+ |
+help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
+ |
+LL | println!(“hello world");
+ | ~
+
+error: expected `,`, found `world`
+ --> $DIR/unicode-quote-chars.rs:2:21
+ |
+LL | println!(“hello world”);
+ | ^^^^^ expected `,`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs
new file mode 100644
index 000000000..f56013266
--- /dev/null
+++ b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.rs
@@ -0,0 +1,11 @@
+struct S {
+ x: usize,
+ y: usize,
+}
+
+fn main() {
+ S { x: 4,
+ y: 5 };
+}
+
+fn foo() { //~ ERROR this file contains an unclosed delimiter
diff --git a/src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr
new file mode 100644
index 000000000..430a13e6e
--- /dev/null
+++ b/src/test/ui/parser/unmatched-delimiter-at-end-of-file.stderr
@@ -0,0 +1,8 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/unmatched-delimiter-at-end-of-file.rs:11:63
+ |
+LL | fn foo() {
+ | - unclosed delimiter ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unmatched-langle-1.rs b/src/test/ui/parser/unmatched-langle-1.rs
new file mode 100644
index 000000000..fdf2ae398
--- /dev/null
+++ b/src/test/ui/parser/unmatched-langle-1.rs
@@ -0,0 +1,9 @@
+// Check that a suggestion is issued if there are too many `<`s in a
+// generic argument list, and that the parser recovers properly.
+
+fn main() {
+ foo::<<<<Ty<i32>>();
+ //~^ ERROR: unmatched angle brackets
+ //~| ERROR: cannot find function `foo` in this scope [E0425]
+ //~| ERROR: cannot find type `Ty` in this scope [E0412]
+}
diff --git a/src/test/ui/parser/unmatched-langle-1.stderr b/src/test/ui/parser/unmatched-langle-1.stderr
new file mode 100644
index 000000000..c8072b4c5
--- /dev/null
+++ b/src/test/ui/parser/unmatched-langle-1.stderr
@@ -0,0 +1,22 @@
+error: unmatched angle brackets
+ --> $DIR/unmatched-langle-1.rs:5:10
+ |
+LL | foo::<<<<Ty<i32>>();
+ | ^^^ help: remove extra angle brackets
+
+error[E0425]: cannot find function `foo` in this scope
+ --> $DIR/unmatched-langle-1.rs:5:5
+ |
+LL | foo::<<<<Ty<i32>>();
+ | ^^^ not found in this scope
+
+error[E0412]: cannot find type `Ty` in this scope
+ --> $DIR/unmatched-langle-1.rs:5:14
+ |
+LL | foo::<<<<Ty<i32>>();
+ | ^^ not found in this scope
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/unmatched-langle-2.rs b/src/test/ui/parser/unmatched-langle-2.rs
new file mode 100644
index 000000000..8de0d7d89
--- /dev/null
+++ b/src/test/ui/parser/unmatched-langle-2.rs
@@ -0,0 +1,15 @@
+// When there are too many opening `<`s, the compiler would previously
+// suggest nonsense if the `<`s were interspersed with other tokens:
+//
+// error: unmatched angle brackets
+// --> unmatched-langle.rs:2:10
+// |
+// 2 | foo::<Ty<<<i32>();
+// | ^^^ help: remove extra angle brackets
+//
+// This test makes sure that this is no longer happening.
+
+fn main() {
+ foo::<Ty<<<i32>();
+ //~^ ERROR: expected `::`, found `(`
+}
diff --git a/src/test/ui/parser/unmatched-langle-2.stderr b/src/test/ui/parser/unmatched-langle-2.stderr
new file mode 100644
index 000000000..773bb33d8
--- /dev/null
+++ b/src/test/ui/parser/unmatched-langle-2.stderr
@@ -0,0 +1,8 @@
+error: expected `::`, found `(`
+ --> $DIR/unmatched-langle-2.rs:13:20
+ |
+LL | foo::<Ty<<<i32>();
+ | ^ expected `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unsafe-foreign-mod-2.rs b/src/test/ui/parser/unsafe-foreign-mod-2.rs
new file mode 100644
index 000000000..77856fb67
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod-2.rs
@@ -0,0 +1,8 @@
+extern "C" unsafe {
+ //~^ ERROR expected `{`, found keyword `unsafe`
+ //~| ERROR extern block cannot be declared unsafe
+ unsafe fn foo();
+ //~^ ERROR functions in `extern` blocks cannot have qualifiers
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-foreign-mod-2.stderr b/src/test/ui/parser/unsafe-foreign-mod-2.stderr
new file mode 100644
index 000000000..7cc2de141
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod-2.stderr
@@ -0,0 +1,28 @@
+error: expected `{`, found keyword `unsafe`
+ --> $DIR/unsafe-foreign-mod-2.rs:1:12
+ |
+LL | extern "C" unsafe {
+ | ^^^^^^ expected `{`
+
+error: extern block cannot be declared unsafe
+ --> $DIR/unsafe-foreign-mod-2.rs:1:12
+ |
+LL | extern "C" unsafe {
+ | ^^^^^^
+
+error: functions in `extern` blocks cannot have qualifiers
+ --> $DIR/unsafe-foreign-mod-2.rs:4:15
+ |
+LL | extern "C" unsafe {
+ | ----------------- in this `extern` block
+...
+LL | unsafe fn foo();
+ | ^^^
+ |
+help: remove the qualifiers
+ |
+LL | fn foo();
+ | ~~
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/unsafe-foreign-mod.rs b/src/test/ui/parser/unsafe-foreign-mod.rs
new file mode 100644
index 000000000..eab134a4a
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod.rs
@@ -0,0 +1,5 @@
+unsafe extern "C" {
+ //~^ ERROR extern block cannot be declared unsafe
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-foreign-mod.stderr b/src/test/ui/parser/unsafe-foreign-mod.stderr
new file mode 100644
index 000000000..4acf72c5d
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod.stderr
@@ -0,0 +1,8 @@
+error: extern block cannot be declared unsafe
+ --> $DIR/unsafe-foreign-mod.rs:1:1
+ |
+LL | unsafe extern "C" {
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unsafe-mod.rs b/src/test/ui/parser/unsafe-mod.rs
new file mode 100644
index 000000000..7916d878e
--- /dev/null
+++ b/src/test/ui/parser/unsafe-mod.rs
@@ -0,0 +1,9 @@
+unsafe mod m {
+ //~^ ERROR module cannot be declared unsafe
+}
+
+unsafe mod n;
+//~^ ERROR module cannot be declared unsafe
+//~^^ ERROR file not found for module `n`
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-mod.stderr b/src/test/ui/parser/unsafe-mod.stderr
new file mode 100644
index 000000000..dac6e7a35
--- /dev/null
+++ b/src/test/ui/parser/unsafe-mod.stderr
@@ -0,0 +1,23 @@
+error[E0583]: file not found for module `n`
+ --> $DIR/unsafe-mod.rs:5:1
+ |
+LL | unsafe mod n;
+ | ^^^^^^^^^^^^^
+ |
+ = help: to create the module `n`, create file "$DIR/n.rs" or "$DIR/n/mod.rs"
+
+error: module cannot be declared unsafe
+ --> $DIR/unsafe-mod.rs:1:1
+ |
+LL | unsafe mod m {
+ | ^^^^^^
+
+error: module cannot be declared unsafe
+ --> $DIR/unsafe-mod.rs:5:1
+ |
+LL | unsafe mod n;
+ | ^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/parser/unsized.rs b/src/test/ui/parser/unsized.rs
new file mode 100644
index 000000000..e7fd7a196
--- /dev/null
+++ b/src/test/ui/parser/unsized.rs
@@ -0,0 +1,7 @@
+// Test syntax checks for `type` keyword.
+
+struct S1 for type;
+//~^ ERROR expected `where`, `{`, `(`, or `;` after struct name, found keyword `for`
+
+pub fn main() {
+}
diff --git a/src/test/ui/parser/unsized.stderr b/src/test/ui/parser/unsized.stderr
new file mode 100644
index 000000000..3d4ed526b
--- /dev/null
+++ b/src/test/ui/parser/unsized.stderr
@@ -0,0 +1,8 @@
+error: expected `where`, `{`, `(`, or `;` after struct name, found keyword `for`
+ --> $DIR/unsized.rs:3:11
+ |
+LL | struct S1 for type;
+ | ^^^ expected `where`, `{`, `(`, or `;` after struct name
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unsized2.rs b/src/test/ui/parser/unsized2.rs
new file mode 100644
index 000000000..21370b329
--- /dev/null
+++ b/src/test/ui/parser/unsized2.rs
@@ -0,0 +1,7 @@
+// Test syntax checks for `type` keyword.
+
+fn f<X>() {}
+
+pub fn main() {
+ f<type>(); //~ ERROR expected expression, found keyword `type`
+}
diff --git a/src/test/ui/parser/unsized2.stderr b/src/test/ui/parser/unsized2.stderr
new file mode 100644
index 000000000..17e39b292
--- /dev/null
+++ b/src/test/ui/parser/unsized2.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found keyword `type`
+ --> $DIR/unsized2.rs:6:7
+ |
+LL | f<type>();
+ | ^^^^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs
new file mode 100644
index 000000000..b4bb48418
--- /dev/null
+++ b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.rs
@@ -0,0 +1,2 @@
+use std::any:: as foo; //~ ERROR expected identifier, found keyword `as`
+//~^ ERROR: expected one of `::`, `;`, or `as`, found `foo`
diff --git a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
new file mode 100644
index 000000000..192ab5eb7
--- /dev/null
+++ b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
@@ -0,0 +1,14 @@
+error: expected identifier, found keyword `as`
+ --> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:16
+ |
+LL | use std::any:: as foo;
+ | ^^ expected identifier, found keyword
+
+error: expected one of `::`, `;`, or `as`, found `foo`
+ --> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:19
+ |
+LL | use std::any:: as foo;
+ | ^^^ expected one of `::`, `;`, or `as`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/use-ends-with-mod-sep.rs b/src/test/ui/parser/use-ends-with-mod-sep.rs
new file mode 100644
index 000000000..ad8da4d18
--- /dev/null
+++ b/src/test/ui/parser/use-ends-with-mod-sep.rs
@@ -0,0 +1 @@
+use std::any::; //~ ERROR expected identifier, found `;`
diff --git a/src/test/ui/parser/use-ends-with-mod-sep.stderr b/src/test/ui/parser/use-ends-with-mod-sep.stderr
new file mode 100644
index 000000000..bd0d881a0
--- /dev/null
+++ b/src/test/ui/parser/use-ends-with-mod-sep.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `;`
+ --> $DIR/use-ends-with-mod-sep.rs:1:15
+ |
+LL | use std::any::;
+ | ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/use-unclosed-brace.rs b/src/test/ui/parser/use-unclosed-brace.rs
new file mode 100644
index 000000000..41742f37f
--- /dev/null
+++ b/src/test/ui/parser/use-unclosed-brace.rs
@@ -0,0 +1,12 @@
+// error-pattern: expected one of `,`, `::`, `as`, or `}`, found `;`
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: expected item, found `}`
+use foo::{bar, baz;
+
+use std::fmt::Display;
+
+mod bar { }
+
+mod baz { }
+
+fn main() {}
diff --git a/src/test/ui/parser/use-unclosed-brace.stderr b/src/test/ui/parser/use-unclosed-brace.stderr
new file mode 100644
index 000000000..438fe9c47
--- /dev/null
+++ b/src/test/ui/parser/use-unclosed-brace.stderr
@@ -0,0 +1,27 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/use-unclosed-brace.rs:12:14
+ |
+LL | use foo::{bar, baz;
+ | - unclosed delimiter
+...
+LL | fn main() {}
+ | ^
+
+error: expected one of `,`, `::`, `as`, or `}`, found `;`
+ --> $DIR/use-unclosed-brace.rs:4:10
+ |
+LL | use foo::{bar, baz;
+ | ^ ^
+ | | |
+ | | expected one of `,`, `::`, `as`, or `}`
+ | | help: `}` may belong here
+ | unclosed delimiter
+
+error: expected item, found `}`
+ --> $DIR/use-unclosed-brace.rs:12:14
+ |
+LL | fn main() {}
+ | ^ expected item
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/parser/utf16-be-without-bom.rs b/src/test/ui/parser/utf16-be-without-bom.rs
new file mode 100644
index 000000000..22aa19717
--- /dev/null
+++ b/src/test/ui/parser/utf16-be-without-bom.rs
Binary files differ
diff --git a/src/test/ui/parser/utf16-be-without-bom.stderr b/src/test/ui/parser/utf16-be-without-bom.stderr
new file mode 100644
index 000000000..768d2c531
--- /dev/null
+++ b/src/test/ui/parser/utf16-be-without-bom.stderr
Binary files differ
diff --git a/src/test/ui/parser/utf16-le-without-bom.rs b/src/test/ui/parser/utf16-le-without-bom.rs
new file mode 100644
index 000000000..3c1049929
--- /dev/null
+++ b/src/test/ui/parser/utf16-le-without-bom.rs
Binary files differ
diff --git a/src/test/ui/parser/utf16-le-without-bom.stderr b/src/test/ui/parser/utf16-le-without-bom.stderr
new file mode 100644
index 000000000..4f4b91e39
--- /dev/null
+++ b/src/test/ui/parser/utf16-le-without-bom.stderr
Binary files differ
diff --git a/src/test/ui/parser/utf8_idents-rpass.rs b/src/test/ui/parser/utf8_idents-rpass.rs
new file mode 100644
index 000000000..206744a58
--- /dev/null
+++ b/src/test/ui/parser/utf8_idents-rpass.rs
@@ -0,0 +1,39 @@
+// run-pass
+//
+#![allow(non_snake_case)]
+
+pub fn main() {
+ let ε = 0.00001f64;
+ let Π = 3.14f64;
+ let लंच = Π * Π + 1.54;
+ assert!(((लंच - 1.54) - (Π * Π)).abs() < ε);
+ assert_eq!(საჭმელად_გემრიელი_სადილი(), 0);
+}
+
+fn საჭმელად_გემრიელი_სადილი() -> isize {
+
+ // Lunch in several languages.
+
+ let ランチ = 10;
+ let 午餐 = 10;
+
+ let ארוחת_צהריי = 10;
+ let غداء = 10_usize;
+ let լանչ = 10;
+ let обед = 10;
+ let абед = 10;
+ let μεσημεριανό = 10;
+ let hádegismatur = 10;
+ let ручек = 10;
+
+ let ăn_trưa = 10;
+ let อาหารกลางวัน = 10;
+
+ // Lunchy arithmetic, mm.
+
+ assert_eq!(hádegismatur * ручек * обед, 1000);
+ assert_eq!(10, ארוחת_צהריי);
+ assert_eq!(ランチ + 午餐 + μεσημεριανό, 30);
+ assert_eq!(ăn_trưa + อาหารกลางวัน, 20);
+ return (абед + լանչ) >> غداء;
+}
diff --git a/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs
new file mode 100644
index 000000000..9eeee195e
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs
@@ -0,0 +1,9 @@
+fn f1<'a>(x: u8, y: &'a ...) {}
+//~^ ERROR C-variadic type `...` may not be nested inside another type
+
+fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
+//~^ ERROR C-variadic type `...` may not be nested inside another type
+
+fn main() {
+ let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
new file mode 100644
index 000000000..8b9d676a4
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
@@ -0,0 +1,24 @@
+error[E0743]: C-variadic type `...` may not be nested inside another type
+ --> $DIR/variadic-ffi-nested-syntactic-fail.rs:1:25
+ |
+LL | fn f1<'a>(x: u8, y: &'a ...) {}
+ | ^^^
+
+error[E0743]: C-variadic type `...` may not be nested inside another type
+ --> $DIR/variadic-ffi-nested-syntactic-fail.rs:4:29
+ |
+LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
+ | ^^^
+
+error[E0308]: mismatched types
+ --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33
+ |
+LL | let _recovery_witness: () = 0;
+ | -- ^ expected `()`, found integer
+ | |
+ | expected due to this
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0743.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs
new file mode 100644
index 000000000..0b61e267d
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs
@@ -0,0 +1,77 @@
+#![feature(c_variadic)]
+#![allow(anonymous_parameters)]
+
+fn main() {}
+
+fn f1_1(x: isize, ...) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+
+fn f1_2(...) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+//~| ERROR C-variadic function must be declared with at least one named argument
+
+extern "C" fn f2_1(x: isize, ...) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+
+extern "C" fn f2_2(...) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+//~| ERROR C-variadic function must be declared with at least one named argument
+
+extern "C" fn f2_3(..., x: isize) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+//~| ERROR `...` must be the last argument of a C-variadic function
+
+extern "C" fn f3_1(x: isize, ...) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+
+extern "C" fn f3_2(...) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+//~| ERROR C-variadic function must be declared with at least one named argument
+
+extern "C" fn f3_3(..., x: isize) {}
+//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+//~| ERROR `...` must be the last argument of a C-variadic function
+
+extern "C" {
+ fn e_f1(...);
+ //~^ ERROR C-variadic function must be declared with at least one named argument
+ fn e_f2(..., x: isize);
+//~^ ERROR `...` must be the last argument of a C-variadic function
+}
+
+struct X;
+
+impl X {
+ fn i_f1(x: isize, ...) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ fn i_f2(...) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR C-variadic function must be declared with at least one named argument
+ fn i_f3(..., x: isize, ...) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR `...` must be the last argument of a C-variadic function
+ fn i_f4(..., x: isize, ...) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR `...` must be the last argument of a C-variadic function
+}
+
+trait T {
+ fn t_f1(x: isize, ...) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ fn t_f2(x: isize, ...);
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ fn t_f3(...) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR C-variadic function must be declared with at least one named argument
+ fn t_f4(...);
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR C-variadic function must be declared with at least one named argument
+ fn t_f5(..., x: isize) {}
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR `...` must be the last argument of a C-variadic function
+ fn t_f6(..., x: isize);
+ //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+ //~| ERROR `...` must be the last argument of a C-variadic function
+}
diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr
new file mode 100644
index 000000000..f1cbbb279
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr
@@ -0,0 +1,206 @@
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19
+ |
+LL | fn f1_1(x: isize, ...) {}
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
+ |
+LL | fn f1_2(...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
+ |
+LL | fn f1_2(...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:13:30
+ |
+LL | extern "C" fn f2_1(x: isize, ...) {}
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20
+ |
+LL | extern "C" fn f2_2(...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20
+ |
+LL | extern "C" fn f2_2(...) {}
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20
+ |
+LL | extern "C" fn f2_3(..., x: isize) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20
+ |
+LL | extern "C" fn f2_3(..., x: isize) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30
+ |
+LL | extern "C" fn f3_1(x: isize, ...) {}
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
+ |
+LL | extern "C" fn f3_2(...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
+ |
+LL | extern "C" fn f3_2(...) {}
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20
+ |
+LL | extern "C" fn f3_3(..., x: isize) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20
+ |
+LL | extern "C" fn f3_3(..., x: isize) {}
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:36:13
+ |
+LL | fn e_f1(...);
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:38:13
+ |
+LL | fn e_f2(..., x: isize);
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:45:23
+ |
+LL | fn i_f1(x: isize, ...) {}
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13
+ |
+LL | fn i_f2(...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13
+ |
+LL | fn i_f2(...) {}
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
+ |
+LL | fn i_f3(..., x: isize, ...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
+ |
+LL | fn i_f3(..., x: isize, ...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:50:28
+ |
+LL | fn i_f3(..., x: isize, ...) {}
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
+ |
+LL | fn i_f4(..., x: isize, ...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
+ |
+LL | fn i_f4(..., x: isize, ...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:54:28
+ |
+LL | fn i_f4(..., x: isize, ...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:61:23
+ |
+LL | fn t_f1(x: isize, ...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:63:23
+ |
+LL | fn t_f2(x: isize, ...);
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
+ |
+LL | fn t_f3(...) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
+ |
+LL | fn t_f3(...) {}
+ | ^^^
+
+error: C-variadic function must be declared with at least one named argument
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:68:13
+ |
+LL | fn t_f4(...);
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:68:13
+ |
+LL | fn t_f4(...);
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:71:13
+ |
+LL | fn t_f5(..., x: isize) {}
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:71:13
+ |
+LL | fn t_f5(..., x: isize) {}
+ | ^^^
+
+error: `...` must be the last argument of a C-variadic function
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:74:13
+ |
+LL | fn t_f6(..., x: isize);
+ | ^^^
+
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:74:13
+ |
+LL | fn t_f6(..., x: isize);
+ | ^^^
+
+error: aborting due to 34 previous errors
+
diff --git a/src/test/ui/parser/variadic-ffi-syntactic-pass.rs b/src/test/ui/parser/variadic-ffi-syntactic-pass.rs
new file mode 100644
index 000000000..3875d6af1
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-syntactic-pass.rs
@@ -0,0 +1,53 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn f1_1(x: isize, ...) {}
+
+#[cfg(FALSE)]
+fn f1_2(...) {}
+
+#[cfg(FALSE)]
+extern "C" fn f2_1(x: isize, ...) {}
+
+#[cfg(FALSE)]
+extern "C" fn f2_2(...) {}
+
+#[cfg(FALSE)]
+extern "C" fn f2_3(..., x: isize) {}
+
+#[cfg(FALSE)]
+extern fn f3_1(x: isize, ...) {}
+
+#[cfg(FALSE)]
+extern fn f3_2(...) {}
+
+#[cfg(FALSE)]
+extern fn f3_3(..., x: isize) {}
+
+#[cfg(FALSE)]
+extern {
+ fn e_f1(...);
+ fn e_f2(..., x: isize);
+}
+
+struct X;
+
+#[cfg(FALSE)]
+impl X {
+ fn i_f1(x: isize, ...) {}
+ fn i_f2(...) {}
+ fn i_f3(..., x: isize, ...) {}
+ fn i_f4(..., x: isize, ...) {}
+}
+
+#[cfg(FALSE)]
+trait T {
+ fn t_f1(x: isize, ...) {}
+ fn t_f2(x: isize, ...);
+ fn t_f3(...) {}
+ fn t_f4(...);
+ fn t_f5(..., x: isize) {}
+ fn t_f6(..., x: isize);
+}
diff --git a/src/test/ui/parser/virtual-structs.rs b/src/test/ui/parser/virtual-structs.rs
new file mode 100644
index 000000000..ce57a3454
--- /dev/null
+++ b/src/test/ui/parser/virtual-structs.rs
@@ -0,0 +1,10 @@
+// Test diagnostics for the removed struct inheritance feature.
+
+virtual struct SuperStruct {
+//~^ ERROR expected item, found reserved keyword `virtual`
+ f1: isize,
+}
+
+struct Struct : SuperStruct;
+
+pub fn main() {}
diff --git a/src/test/ui/parser/virtual-structs.stderr b/src/test/ui/parser/virtual-structs.stderr
new file mode 100644
index 000000000..a5211d83f
--- /dev/null
+++ b/src/test/ui/parser/virtual-structs.stderr
@@ -0,0 +1,8 @@
+error: expected item, found reserved keyword `virtual`
+ --> $DIR/virtual-structs.rs:3:1
+ |
+LL | virtual struct SuperStruct {
+ | ^^^^^^^ expected item
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs
new file mode 100644
index 000000000..e80db5372
--- /dev/null
+++ b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.rs
@@ -0,0 +1,15 @@
+// Empty predicate list is OK
+fn equal1<T>(_: &T, _: &T) -> bool where {
+ true
+}
+
+// Empty bound list is OK
+fn equal2<T>(_: &T, _: &T) -> bool where T: {
+ true
+}
+
+fn foo<'a>() where 'a {}
+//~^ ERROR expected `:`, found `{`
+
+fn main() {
+}
diff --git a/src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr
new file mode 100644
index 000000000..b80b0a409
--- /dev/null
+++ b/src/test/ui/parser/where-clauses-no-bounds-or-predicates.stderr
@@ -0,0 +1,8 @@
+error: expected `:`, found `{`
+ --> $DIR/where-clauses-no-bounds-or-predicates.rs:11:23
+ |
+LL | fn foo<'a>() where 'a {}
+ | ^ expected `:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/where_with_bound.rs b/src/test/ui/parser/where_with_bound.rs
new file mode 100644
index 000000000..3ca45f188
--- /dev/null
+++ b/src/test/ui/parser/where_with_bound.rs
@@ -0,0 +1,5 @@
+fn foo<T>() where <T>::Item: ToString, T: Iterator { }
+//~^ ERROR generic parameters on `where` clauses are reserved for future use
+//~| ERROR cannot find type `Item` in the crate root
+
+fn main() {}
diff --git a/src/test/ui/parser/where_with_bound.stderr b/src/test/ui/parser/where_with_bound.stderr
new file mode 100644
index 000000000..ff98b3f5f
--- /dev/null
+++ b/src/test/ui/parser/where_with_bound.stderr
@@ -0,0 +1,15 @@
+error: generic parameters on `where` clauses are reserved for future use
+ --> $DIR/where_with_bound.rs:1:19
+ |
+LL | fn foo<T>() where <T>::Item: ToString, T: Iterator { }
+ | ^^^ currently unsupported
+
+error[E0412]: cannot find type `Item` in the crate root
+ --> $DIR/where_with_bound.rs:1:24
+ |
+LL | fn foo<T>() where <T>::Item: ToString, T: Iterator { }
+ | ^^^^ not found in the crate root
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/while-if-let-without-body.rs b/src/test/ui/parser/while-if-let-without-body.rs
new file mode 100644
index 000000000..063c0145c
--- /dev/null
+++ b/src/test/ui/parser/while-if-let-without-body.rs
@@ -0,0 +1,13 @@
+fn main() {
+ let container = vec![Some(1), Some(2), None];
+
+ let mut i = 0;
+ while if let Some(thing) = container.get(i) {
+ //~^ NOTE while parsing the body of this `while` expression
+ //~| NOTE this `while` condition successfully parsed
+ println!("{:?}", thing);
+ i += 1;
+ }
+}
+//~^ ERROR expected `{`, found `}`
+//~| NOTE expected `{`
diff --git a/src/test/ui/parser/while-if-let-without-body.stderr b/src/test/ui/parser/while-if-let-without-body.stderr
new file mode 100644
index 000000000..2dac45c11
--- /dev/null
+++ b/src/test/ui/parser/while-if-let-without-body.stderr
@@ -0,0 +1,18 @@
+error: expected `{`, found `}`
+ --> $DIR/while-if-let-without-body.rs:11:1
+ |
+LL | while if let Some(thing) = container.get(i) {
+ | _____-----_-
+ | | |
+ | | while parsing the body of this `while` expression
+LL | |
+LL | |
+LL | | println!("{:?}", thing);
+LL | | i += 1;
+LL | | }
+ | |_____- this `while` condition successfully parsed
+LL | }
+ | ^ expected `{`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.rs b/src/test/ui/parser/wrong-escape-of-curly-braces.rs
new file mode 100644
index 000000000..8e5258acd
--- /dev/null
+++ b/src/test/ui/parser/wrong-escape-of-curly-braces.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let ok = "{{everything fine}}";
+ let bad = "\{it is wrong\}";
+ //~^ ERROR unknown character escape: `{`
+ //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}`
+ //~| ERROR unknown character escape: `}`
+ //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}`
+}
diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
new file mode 100644
index 000000000..ff1a2fb0f
--- /dev/null
+++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
@@ -0,0 +1,18 @@
+error: unknown character escape: `{`
+ --> $DIR/wrong-escape-of-curly-braces.rs:3:17
+ |
+LL | let bad = "\{it is wrong\}";
+ | ^ unknown character escape
+ |
+ = help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
+
+error: unknown character escape: `}`
+ --> $DIR/wrong-escape-of-curly-braces.rs:3:30
+ |
+LL | let bad = "\{it is wrong\}";
+ | ^ unknown character escape
+ |
+ = help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
+
+error: aborting due to 2 previous errors
+