always make tuple elements a coercion site

This commit is contained in:
Waffle Lapkin
2025-10-17 14:30:57 +02:00
parent 36e5a99db0
commit 3398ea27ce
8 changed files with 34 additions and 50 deletions
+13 -16
View File
@@ -1792,27 +1792,24 @@ fn check_expr_repeat(
fn check_expr_tuple(
&self,
elts: &'tcx [hir::Expr<'tcx>],
elements: &'tcx [hir::Expr<'tcx>],
expected: Expectation<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> {
let flds = expected.only_has_type(self).and_then(|ty| {
let ty = self.try_structurally_resolve_type(expr.span, ty);
match ty.kind() {
ty::Tuple(flds) => Some(&flds[..]),
_ => None,
}
let mut expectations = expected
.only_has_type(self)
.and_then(|ty| self.try_structurally_resolve_type(expr.span, ty).opt_tuple_fields())
.unwrap_or_default()
.iter();
let elements = elements.iter().map(|e| {
let ty = expectations.next().unwrap_or_else(|| self.next_ty_var(e.span));
self.check_expr_coercible_to_type(e, ty, None);
ty
});
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
Some(fs) if i < fs.len() => {
let ety = fs[i];
self.check_expr_coercible_to_type(e, ety, None);
ety
}
_ => self.check_expr_with_expectation(e, NoExpectation),
});
let tuple = Ty::new_tup_from_iter(self.tcx, elt_ts_iter);
let tuple = Ty::new_tup_from_iter(self.tcx, elements);
if let Err(guar) = tuple.error_reported() {
Ty::new_error(self.tcx, guar)
} else {
+11 -1
View File
@@ -1592,7 +1592,8 @@ pub fn ty_adt_def(self) -> Option<AdtDef<'tcx>> {
}
}
/// Iterates over tuple fields.
/// Returns a list of tuple type arguments.
///
/// Panics when called on anything but a tuple.
#[inline]
pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
@@ -1602,6 +1603,15 @@ pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
}
}
/// Returns a list of tuple type arguments, or `None` if `self` isn't a tuple.
#[inline]
pub fn opt_tuple_fields(self) -> Option<&'tcx List<Ty<'tcx>>> {
match self.kind() {
Tuple(args) => Some(args),
_ => None,
}
}
/// If the type contains variants, returns the valid range of variant indices.
//
// FIXME: This requires the optimized MIR in the case of coroutines.
+2 -2
View File
@@ -232,10 +232,10 @@ LL | break (break, break);
| || |
| || expected because of this `break`
| |expected because of this `break`
| expected `()`, found `(!, !)`
| expected `()`, found `(_, _)`
|
= note: expected unit type `()`
found tuple `(!, !)`
found tuple `(_, _)`
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:89:15
@@ -22,10 +22,10 @@ error[E0308]: mismatched types
LL | fn f() -> isize {
| ----- expected `isize` because of return type
LL | (return 1, return 2)
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `(!, !)`
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `(_, _)`
|
= note: expected type `isize`
found tuple `(!, !)`
found tuple `(_, _)`
error: aborting due to 2 previous errors
+1 -1
View File
@@ -1,7 +1,7 @@
fn main() {
let _tmp = [
("C200B40A82", 3),
("C200B40A83", 4) //~ ERROR: expected function, found `(&'static str, {integer})` [E0618]
("C200B40A83", 4) //~ ERROR: expected function, found `(&str, {integer})` [E0618]
("C200B40A8537", 5),
];
}
+1 -1
View File
@@ -1,4 +1,4 @@
error[E0618]: expected function, found `(&'static str, {integer})`
error[E0618]: expected function, found `(&str, {integer})`
--> $DIR/array-diagnostics.rs:4:9
|
LL | ("C200B40A83", 4)
+4 -2
View File
@@ -3,12 +3,14 @@
// unifying match arms, for example.
//
// See also coercion-slice.rs
//
//@ check-pass
fn main() {
let _: ((),) = (loop {},);
((),) = (loop {},); //~ error: mismatched types
((),) = (loop {},);
let x = (loop {},);
let _: ((),) = x; //~ error: mismatched types
let _: ((),) = x;
}
-25
View File
@@ -1,25 +0,0 @@
error[E0308]: mismatched types
--> $DIR/coercion-never.rs:10:6
|
LL | ((),) = (loop {},);
| ^^ ---------- this expression has type `(!,)`
| |
| expected `!`, found `()`
|
= note: expected type `!`
found unit type `()`
error[E0308]: mismatched types
--> $DIR/coercion-never.rs:13:20
|
LL | let _: ((),) = x;
| ----- ^ expected `((),)`, found `(!,)`
| |
| expected due to this
|
= note: expected tuple `((),)`
found tuple `(!,)`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.