mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
always make tuple elements a coercion site
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,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,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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
Reference in New Issue
Block a user