Skip to content

Commit 09abbbd

Browse files
committed
auto merge of #16866 : P1start/rust/tuple-indexing, r=brson
This allows code to access the fields of tuples and tuple structs behind the feature gate `tuple_indexing`: ```rust #![feature(tuple_indexing)] let x = (1i, 2i); assert_eq!(x.1, 2); struct Point(int, int); let origin = Point(0, 0); assert_eq!(origin.0, 0); assert_eq!(origin.1, 0); ``` Implements [RFC 53](https://github.com/rust-lang/rfcs/blob/master/active/0053-tuple-accessors.md). Closes #16950.
2 parents 9f6d27c + bf274bc commit 09abbbd

34 files changed

+549
-14
lines changed

src/doc/rust.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,6 +2555,8 @@ The currently implemented features of the reference compiler are:
25552555
which is considered wildly unsafe and will be
25562556
obsoleted by language improvements.
25572557

2558+
* `tuple_indexing` - Allows use of tuple indexing (expressions like `expr.0`)
2559+
25582560
If a feature is promoted to a language feature, then all existing programs will
25592561
start to receive compilation warnings about #[feature] directives which enabled
25602562
the new feature (because the directive is no longer necessary). However, if

src/librustc/front/feature_gate.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
7070
("unboxed_closures", Active),
7171
("import_shadowing", Active),
7272
("advanced_slice_patterns", Active),
73+
("tuple_indexing", Active),
7374

7475
// if you change this list without updating src/doc/rust.md, cmr will be sad
7576

@@ -338,6 +339,11 @@ impl<'a> Visitor<()> for Context<'a> {
338339
"unboxed closures are a work-in-progress \
339340
feature with known bugs");
340341
}
342+
ast::ExprTupField(..) => {
343+
self.gate_feature("tuple_indexing",
344+
e.span,
345+
"tuple indexing is experimental");
346+
}
341347
_ => {}
342348
}
343349
visit::walk_expr(self, e, ());

src/librustc/lint/builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,7 @@ impl UnnecessaryParens {
10561056
ast::ExprUnary(_, ref x) |
10571057
ast::ExprCast(ref x, _) |
10581058
ast::ExprField(ref x, _, _) |
1059+
ast::ExprTupField(ref x, _, _) |
10591060
ast::ExprIndex(ref x, _) => {
10601061
// &X { y: 1 }, X { y: 1 }.y
10611062
contains_exterior_struct_lit(&**x)

src/librustc/middle/borrowck/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
807807
out.push_str(token::get_name(fname).get());
808808
}
809809
mc::PositionalField(idx) => {
810-
out.push_char('#'); // invent a notation here
810+
out.push_char('.');
811811
out.push_str(idx.to_string().as_slice());
812812
}
813813
}

src/librustc/middle/cfg/construct.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
467467
ast::ExprCast(e, _) |
468468
ast::ExprUnary(_, e) |
469469
ast::ExprParen(e) |
470-
ast::ExprField(e, _, _) => {
470+
ast::ExprField(e, _, _) |
471+
ast::ExprTupField(e, _, _) => {
471472
self.straightline(expr, pred, [e])
472473
}
473474

src/librustc/middle/check_const.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
173173
ExprAddrOf(MutImmutable, _) |
174174
ExprParen(..) |
175175
ExprField(..) |
176+
ExprTupField(..) |
176177
ExprIndex(..) |
177178
ExprTup(..) |
178179
ExprRepeat(..) |

src/librustc/middle/check_static.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
106106
}
107107

108108
match e.node {
109-
ast::ExprField(..) | ast::ExprVec(..) |
109+
ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) |
110110
ast::ExprBlock(..) | ast::ExprTup(..) => {
111111
visit::walk_expr(self, e, is_const);
112112
}

src/librustc/middle/const_eval.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
225225

226226
ast::ExprField(ref base, _, _) => self.classify(&**base),
227227

228+
ast::ExprTupField(ref base, _, _) => self.classify(&**base),
229+
228230
ast::ExprIndex(ref base, ref idx) =>
229231
join(self.classify(&**base), self.classify(&**idx)),
230232

src/librustc/middle/dead.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
145145
}
146146
}
147147

148+
fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: uint) {
149+
match ty::get(ty::expr_ty_adjusted(self.tcx, lhs)).sty {
150+
ty::ty_struct(id, _) => {
151+
let fields = ty::lookup_struct_fields(self.tcx, id);
152+
let field_id = fields[idx].id;
153+
self.live_symbols.insert(field_id.node);
154+
},
155+
_ => ()
156+
}
157+
}
158+
148159
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
149160
let id = match self.tcx.def_map.borrow().get(&lhs.id) {
150161
&def::DefVariant(_, id, _) => id,
@@ -255,6 +266,9 @@ impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx>
255266
ast::ExprField(ref lhs, ref ident, _) => {
256267
self.handle_field_access(&**lhs, &ident.node);
257268
}
269+
ast::ExprTupField(ref lhs, idx, _) => {
270+
self.handle_tup_field_access(&**lhs, idx.node);
271+
}
258272
_ => ()
259273
}
260274

src/librustc/middle/expr_use_visitor.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
324324
self.select_from_expr(&**base);
325325
}
326326

327+
ast::ExprTupField(ref base, _, _) => { // base.<n>
328+
self.select_from_expr(&**base);
329+
}
330+
327331
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
328332
if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
329333
self.select_from_expr(&**lhs);

0 commit comments

Comments
 (0)