Skip to content

Commit 5e6e9dc

Browse files
committed
always make tuple elements a coercion site
1 parent 95e4a92 commit 5e6e9dc

File tree

10 files changed

+38
-54
lines changed

10 files changed

+38
-54
lines changed

compiler/rustc_hir_typeck/src/expr.rs

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

19401940
fn check_expr_tuple(
19411941
&self,
1942-
elts: &'tcx [hir::Expr<'tcx>],
1942+
elements: &'tcx [hir::Expr<'tcx>],
19431943
expected: Expectation<'tcx>,
19441944
expr: &'tcx hir::Expr<'tcx>,
19451945
) -> Ty<'tcx> {
1946-
let flds = expected.only_has_type(self).and_then(|ty| {
1947-
let ty = self.try_structurally_resolve_type(expr.span, ty);
1948-
match ty.kind() {
1949-
ty::Tuple(flds) => Some(&flds[..]),
1950-
_ => None,
1951-
}
1946+
let mut expectations = expected
1947+
.only_has_type(self)
1948+
.and_then(|ty| self.try_structurally_resolve_type(expr.span, ty).tuple())
1949+
.unwrap_or_default()
1950+
.iter();
1951+
1952+
let elements = elements.iter().map(|e| {
1953+
let ty = expectations.next().unwrap_or_else(|| self.next_ty_var(e.span));
1954+
self.check_expr_coercible_to_type(e, ty, None);
1955+
ty
19521956
});
19531957

1954-
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
1955-
Some(fs) if i < fs.len() => {
1956-
let ety = fs[i];
1957-
self.check_expr_coercible_to_type(e, ety, None);
1958-
ety
1959-
}
1960-
_ => self.check_expr_with_expectation(e, NoExpectation),
1961-
});
1962-
let tuple = Ty::new_tup_from_iter(self.tcx, elt_ts_iter);
1958+
let tuple = Ty::new_tup_from_iter(self.tcx, elements);
1959+
19631960
if let Err(guar) = tuple.error_reported() {
19641961
Ty::new_error(self.tcx, guar)
19651962
} else {

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1560,7 +1560,8 @@ impl<'tcx> Ty<'tcx> {
15601560
}
15611561
}
15621562

1563-
/// Iterates over tuple fields.
1563+
/// Returns a list of tuple fields.
1564+
///
15641565
/// Panics when called on anything but a tuple.
15651566
#[inline]
15661567
pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
@@ -1570,6 +1571,15 @@ impl<'tcx> Ty<'tcx> {
15701571
}
15711572
}
15721573

1574+
/// Returns a list of tuple type arguments, or `None` if `self` isn't a tuple.
1575+
#[inline]
1576+
pub fn tuple(self) -> Option<&'tcx List<Ty<'tcx>>> {
1577+
match self.kind() {
1578+
Tuple(args) => Some(args),
1579+
_ => None,
1580+
}
1581+
}
1582+
15731583
/// If the type contains variants, returns the valid range of variant indices.
15741584
//
15751585
// 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/diverging-tuple-parts-39485.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

tests/ui/never_type/issue-10176.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ fn f() -> isize { //~ NOTE expected `isize` because of return type
22
(return 1, return 2)
33
//~^ ERROR mismatched types
44
//~| NOTE expected type `isize`
5-
//~| NOTE found tuple `(!, !)`
6-
//~| NOTE expected `isize`, found `(!, !)`
5+
//~| NOTE found tuple `(_, _)`
6+
//~| NOTE expected `isize`, found `(_, _)`
77
}
88

99
fn main() {}

tests/ui/never_type/issue-10176.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ error[E0308]: mismatched types
44
LL | fn f() -> isize {
55
| ----- expected `isize` because of return type
66
LL | (return 1, return 2)
7-
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `(!, !)`
7+
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `(_, _)`
88
|
99
= note: expected type `isize`
10-
found tuple `(!, !)`
10+
found tuple `(_, _)`
1111

1212
error: aborting due to 1 previous error
1313

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)