Skip to content

Commit f54533b

Browse files
committed
Allow _ as an expression
1 parent 27e43ae commit f54533b

File tree

7 files changed

+59
-3
lines changed

7 files changed

+59
-3
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,7 @@ impl Expr {
11921192
ExprKind::Field(..) => ExprPrecedence::Field,
11931193
ExprKind::Index(..) => ExprPrecedence::Index,
11941194
ExprKind::Range(..) => ExprPrecedence::Range,
1195+
ExprKind::Underscore => ExprPrecedence::Path,
11951196
ExprKind::Path(..) => ExprPrecedence::Path,
11961197
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
11971198
ExprKind::Break(..) => ExprPrecedence::Break,
@@ -1314,6 +1315,8 @@ pub enum ExprKind {
13141315
Index(P<Expr>, P<Expr>),
13151316
/// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
13161317
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1318+
/// An underscore.
1319+
Underscore,
13171320

13181321
/// Variable reference, possibly containing `::` and/or type
13191322
/// parameters (e.g., `foo::bar::<baz>`).

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
12181218
visit_opt(e1, |e1| vis.visit_expr(e1));
12191219
visit_opt(e2, |e2| vis.visit_expr(e2));
12201220
}
1221+
ExprKind::Underscore => {}
12211222
ExprKind::Path(qself, path) => {
12221223
vis.visit_qself(qself);
12231224
vis.visit_path(path);

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
807807
walk_list!(visitor, visit_expr, start);
808808
walk_list!(visitor, visit_expr, end);
809809
}
810+
ExprKind::Underscore => {}
810811
ExprKind::Path(ref maybe_qself, ref path) => {
811812
if let Some(ref qself) = *maybe_qself {
812813
visitor.visit_ty(&qself.ty);

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,7 @@ impl<'a> State<'a> {
20692069
self.print_expr_maybe_paren(e, fake_prec);
20702070
}
20712071
}
2072+
ast::ExprKind::Underscore => self.s.word("_"),
20722073
ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0),
20732074
ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true),
20742075
ast::ExprKind::Break(opt_label, ref opt_expr) => {

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,8 @@ impl<'a> Parser<'a> {
11161116
} else {
11171117
self.parse_lit_expr(attrs)
11181118
}
1119+
} else if self.eat_keyword(kw::Underscore) {
1120+
Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
11191121
} else {
11201122
self.parse_lit_expr(attrs)
11211123
}

src/test/ui/issues/issue-34334.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
fn main () {
22
let sr: Vec<(u32, _, _) = vec![];
33
//~^ ERROR expected one of `,` or `>`, found `=`
4+
//~| ERROR expected value, found struct `Vec`
5+
//~| ERROR expected value, found builtin type `u32`
6+
//~| ERROR mismatched types
7+
//~| ERROR invalid left-hand side of assignment
8+
//~| ERROR expected expression, found reserved identifier `_`
9+
//~| ERROR expected expression, found reserved identifier `_`
410
let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
511
//~^ ERROR a value of type `Vec<(u32, _, _)>` cannot be built
612
}

src/test/ui/issues/issue-34334.stderr

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,56 @@ LL | let sr: Vec<(u32, _, _) = vec![];
66
| |
77
| while parsing the type for `sr`
88

9-
error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
10-
--> $DIR/issue-34334.rs:4:87
9+
error[E0423]: expected value, found struct `Vec`
10+
--> $DIR/issue-34334.rs:2:13
11+
|
12+
LL | let sr: Vec<(u32, _, _) = vec![];
13+
| ^^^ did you mean `Vec { /* fields */ }`?
14+
15+
error[E0423]: expected value, found builtin type `u32`
16+
--> $DIR/issue-34334.rs:2:18
17+
|
18+
LL | let sr: Vec<(u32, _, _) = vec![];
19+
| ^^^ not a value
20+
21+
error: expected expression, found reserved identifier `_`
22+
--> $DIR/issue-34334.rs:2:23
23+
|
24+
LL | let sr: Vec<(u32, _, _) = vec![];
25+
| ^ expected expression
26+
27+
error: expected expression, found reserved identifier `_`
28+
--> $DIR/issue-34334.rs:2:26
29+
|
30+
LL | let sr: Vec<(u32, _, _) = vec![];
31+
| ^ expected expression
32+
33+
error[E0308]: mismatched types
34+
--> $DIR/issue-34334.rs:2:31
35+
|
36+
LL | let sr: Vec<(u32, _, _) = vec![];
37+
| ^^^^^^ expected `bool`, found struct `std::vec::Vec`
38+
|
39+
= note: expected type `bool`
40+
found struct `std::vec::Vec<_>`
41+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
42+
43+
error[E0070]: invalid left-hand side of assignment
44+
--> $DIR/issue-34334.rs:2:29
45+
|
46+
LL | let sr: Vec<(u32, _, _) = vec![];
47+
| --------------- ^
48+
| |
49+
| cannot assign to this expression
50+
51+
error[E0599]: no method named `iter` found for unit type `()` in the current scope
52+
--> $DIR/issue-34334.rs:10:36
1153
|
1254
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
1355
| ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
1456
|
1557
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
1658

17-
error: aborting due to 2 previous errors
59+
error: aborting due to 8 previous errors
1860

1961
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)