Skip to content

Commit 3398ea2

Browse files
committed
always make tuple elements a coercion site
1 parent 36e5a99 commit 3398ea2

8 files changed

Lines changed: 34 additions & 50 deletions

File tree

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,27 +1792,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17921792

17931793
fn check_expr_tuple(
17941794
&self,
1795-
elts: &'tcx [hir::Expr<'tcx>],
1795+
elements: &'tcx [hir::Expr<'tcx>],
17961796
expected: Expectation<'tcx>,
17971797
expr: &'tcx hir::Expr<'tcx>,
17981798
) -> Ty<'tcx> {
1799-
let flds = expected.only_has_type(self).and_then(|ty| {
1800-
let ty = self.try_structurally_resolve_type(expr.span, ty);
1801-
match ty.kind() {
1802-
ty::Tuple(flds) => Some(&flds[..]),
1803-
_ => None,
1804-
}
1799+
let mut expectations = expected
1800+
.only_has_type(self)
1801+
.and_then(|ty| self.try_structurally_resolve_type(expr.span, ty).opt_tuple_fields())
1802+
.unwrap_or_default()
1803+
.iter();
1804+
1805+
let elements = elements.iter().map(|e| {
1806+
let ty = expectations.next().unwrap_or_else(|| self.next_ty_var(e.span));
1807+
self.check_expr_coercible_to_type(e, ty, None);
1808+
ty
18051809
});
18061810

1807-
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
1808-
Some(fs) if i < fs.len() => {
1809-
let ety = fs[i];
1810-
self.check_expr_coercible_to_type(e, ety, None);
1811-
ety
1812-
}
1813-
_ => self.check_expr_with_expectation(e, NoExpectation),
1814-
});
1815-
let tuple = Ty::new_tup_from_iter(self.tcx, elt_ts_iter);
1811+
let tuple = Ty::new_tup_from_iter(self.tcx, elements);
1812+
18161813
if let Err(guar) = tuple.error_reported() {
18171814
Ty::new_error(self.tcx, guar)
18181815
} else {

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1592,7 +1592,8 @@ impl<'tcx> Ty<'tcx> {
15921592
}
15931593
}
15941594

1595-
/// Iterates over tuple fields.
1595+
/// Returns a list of tuple type arguments.
1596+
///
15961597
/// Panics when called on anything but a tuple.
15971598
#[inline]
15981599
pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
@@ -1602,6 +1603,15 @@ impl<'tcx> Ty<'tcx> {
16021603
}
16031604
}
16041605

1606+
/// Returns a list of tuple type arguments, or `None` if `self` isn't a tuple.
1607+
#[inline]
1608+
pub fn opt_tuple_fields(self) -> Option<&'tcx List<Ty<'tcx>>> {
1609+
match self.kind() {
1610+
Tuple(args) => Some(args),
1611+
_ => None,
1612+
}
1613+
}
1614+
16051615
/// If the type contains variants, returns the valid range of variant indices.
16061616
//
16071617
// FIXME: This requires the optimized MIR in the case of coroutines.

tests/ui/loops/loop-break-value.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,10 @@ LL | break (break, break);
232232
| || |
233233
| || expected because of this `break`
234234
| |expected because of this `break`
235-
| expected `()`, found `(!, !)`
235+
| expected `()`, found `(_, _)`
236236
|
237237
= note: expected unit type `()`
238-
found tuple `(!, !)`
238+
found tuple `(_, _)`
239239

240240
error[E0308]: mismatched types
241241
--> $DIR/loop-break-value.rs:89:15

tests/ui/never_type/regress/divergent-block-with-tail.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ error[E0308]: mismatched types
2222
LL | fn f() -> isize {
2323
| ----- expected `isize` because of return type
2424
LL | (return 1, return 2)
25-
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `(!, !)`
25+
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `(_, _)`
2626
|
2727
= note: expected type `isize`
28-
found tuple `(!, !)`
28+
found tuple `(_, _)`
2929

3030
error: aborting due to 2 previous errors
3131

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
fn main() {
22
let _tmp = [
33
("C200B40A82", 3),
4-
("C200B40A83", 4) //~ ERROR: expected function, found `(&'static str, {integer})` [E0618]
4+
("C200B40A83", 4) //~ ERROR: expected function, found `(&str, {integer})` [E0618]
55
("C200B40A8537", 5),
66
];
77
}

tests/ui/tuple/array-diagnostics.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0618]: expected function, found `(&'static str, {integer})`
1+
error[E0618]: expected function, found `(&str, {integer})`
22
--> $DIR/array-diagnostics.rs:4:9
33
|
44
LL | ("C200B40A83", 4)

tests/ui/tuple/coercion-never.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
// unifying match arms, for example.
44
//
55
// See also coercion-slice.rs
6+
//
7+
//@ check-pass
68

79
fn main() {
810
let _: ((),) = (loop {},);
911

10-
((),) = (loop {},); //~ error: mismatched types
12+
((),) = (loop {},);
1113

1214
let x = (loop {},);
13-
let _: ((),) = x; //~ error: mismatched types
15+
let _: ((),) = x;
1416
}

tests/ui/tuple/coercion-never.stderr

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)