diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 0b1c725ba4082..8850c67d1a9a5 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2022,22 +2022,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let tcx = self.tcx; - let adt_ty = self.try_structurally_resolve_type(path_span, adt_ty); - let adt_ty_hint = expected.only_has_type(self).and_then(|expected| { - self.fudge_inference_if_ok(|| { + // We eagerly constrain the generic arguments of our ADT to + // guide inference if possible. + // + // This is necessary if we need to coerce the field, e.g. see + // tests/ui/traits/next-solver/typeck/guide-ctors.rs. + if let Some(expected) = expected.only_has_type(self) { + let _ = self.commit_if_ok(|_| { let ocx = ObligationCtxt::new(self); ocx.sup(&self.misc(path_span), self.param_env, expected, adt_ty)?; if !ocx.try_evaluate_obligations().is_empty() { - return Err(TypeError::Mismatch); + Err(TypeError::Mismatch) + } else { + Ok(()) } - Ok(self.resolve_vars_if_possible(adt_ty)) - }) - .ok() - }); - if let Some(adt_ty_hint) = adt_ty_hint { - // re-link the variables that the fudging above can create. - self.demand_eqtype(path_span, adt_ty_hint, adt_ty); + }); } + let adt_ty = self.try_structurally_resolve_type(path_span, adt_ty); let ty::Adt(adt, args) = adt_ty.kind() else { span_bug!(path_span, "non-ADT passed to check_expr_struct_fields"); diff --git a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr index 644a7c7717ca9..bbb281bdb2d4d 100644 --- a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr +++ b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr @@ -1,11 +1,3 @@ -error[E0559]: variant `Option<_>::None` has no field named `value` - --> $DIR/drop-track-bad-field-in-fru.rs:6:12 - | -LL | None { value: (), ..Default::default() }.await; - | ^^^^^ `Option<_>::None` does not have this field - | - = note: all struct fields are already assigned - error[E0277]: `Option<_>` is not a future --> $DIR/drop-track-bad-field-in-fru.rs:6:46 | @@ -21,6 +13,14 @@ LL - None { value: (), ..Default::default() }.await; LL + None { value: (), ..Default::default() }; | +error[E0559]: variant `Option<_>::None` has no field named `value` + --> $DIR/drop-track-bad-field-in-fru.rs:6:12 + | +LL | None { value: (), ..Default::default() }.await; + | ^^^^^ `Option<_>::None` does not have this field + | + = note: all struct fields are already assigned + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0559. diff --git a/tests/ui/async-await/issue-98634.stderr b/tests/ui/async-await/issue-98634.stderr index e0739ae3a9b87..4ce3f11e00d51 100644 --- a/tests/ui/async-await/issue-98634.stderr +++ b/tests/ui/async-await/issue-98634.stderr @@ -28,11 +28,15 @@ error[E0271]: expected `callback` to return `Pin>>`, LL | StructAsync { callback }.await; | ^^^^^ expected `Pin>>`, found future | -note: required by a bound in `StructAsync` - --> $DIR/issue-98634.rs:9:35 - | -LL | pub struct StructAsync Pin>>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync` +note: required for `StructAsync impl Future {callback}>` to implement `Future` + --> $DIR/issue-98634.rs:13:9 + | +LL | impl Future for StructAsync + | ^^^^^^ ^^^^^^^^^^^^^^ +LL | where +LL | F: Fn() -> Pin>>, + | --------------------------------- unsatisfied trait bound introduced here + = note: required for `StructAsync impl Future {callback}>` to implement `IntoFuture` error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr index 996b75493e618..1b79722b8667c 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr @@ -1,19 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/issue-72819-generic-in-const-eval.rs:20:12 - | -LL | let x: Arr<{usize::MAX}> = Arr {}; - | ^^^^^^^^^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` -note: required by a bound in `Arr` - --> $DIR/issue-72819-generic-in-const-eval.rs:8:39 - | -LL | struct Arr - | --- required by a bound in this struct -LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, - | ^^^^^^ required by this bound in `Arr` - error[E0308]: mismatched types --> $DIR/issue-72819-generic-in-const-eval.rs:20:32 | @@ -30,6 +14,6 @@ LL | struct Arr LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs index c3c598ce778cd..40ff40ca346c5 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.rs @@ -19,5 +19,4 @@ impl IsTrue for Assert {} fn main() { let x: Arr<{usize::MAX}> = Arr {}; //[full]~^ ERROR mismatched types - //[full]~| ERROR mismatched types } diff --git a/tests/ui/const-generics/issues/issue-73260.rs b/tests/ui/const-generics/issues/issue-73260.rs index aa7ae90a36373..b13f3f3176d2e 100644 --- a/tests/ui/const-generics/issues/issue-73260.rs +++ b/tests/ui/const-generics/issues/issue-73260.rs @@ -14,5 +14,4 @@ impl IsTrue for Assert {} fn main() { let x: Arr<{usize::MAX}> = Arr {}; //~^ ERROR mismatched types - //~| ERROR mismatched types } diff --git a/tests/ui/const-generics/issues/issue-73260.stderr b/tests/ui/const-generics/issues/issue-73260.stderr index c56b45cc8faf1..e010d29ff8f5b 100644 --- a/tests/ui/const-generics/issues/issue-73260.stderr +++ b/tests/ui/const-generics/issues/issue-73260.stderr @@ -1,20 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/issue-73260.rs:15:12 - | -LL | let x: Arr<{usize::MAX}> = Arr {}; - | ^^^^^^^^^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` -note: required by a bound in `Arr` - --> $DIR/issue-73260.rs:5:37 - | -LL | struct Arr - | --- required by a bound in this struct -LL | where -LL | Assert::<{N < usize::MAX / 2}>: IsTrue, - | ^^^^^^ required by this bound in `Arr` - error[E0308]: mismatched types --> $DIR/issue-73260.rs:15:32 | @@ -32,6 +15,6 @@ LL | where LL | Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index befff8802804e..24055641b870c 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `B: Copy` is not satisfied +error[E0277]: the trait bound `B<_>: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:31:26 | LL | is_copy(B { a: 1, b: C }); - | ------- ^ the trait `Copy` is not implemented for `B` + | ------- ^ the trait `Copy` is not implemented for `B<_>` | | | required by a bound introduced by this call | @@ -21,11 +21,11 @@ help: consider borrowing here LL | is_copy(B { a: 1, b: &C }); | + -error[E0277]: the trait bound `B: Clone` is not satisfied +error[E0277]: the trait bound `B<_>: Clone` is not satisfied --> $DIR/deriving-copyclone.rs:32:27 | LL | is_clone(B { a: 1, b: C }); - | -------- ^ the trait `Clone` is not implemented for `B` + | -------- ^ the trait `Clone` is not implemented for `B<_>` | | | required by a bound introduced by this call | @@ -44,11 +44,11 @@ help: consider borrowing here LL | is_clone(B { a: 1, b: &C }); | + -error[E0277]: the trait bound `B: Copy` is not satisfied +error[E0277]: the trait bound `B<_>: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:35:26 | LL | is_copy(B { a: 1, b: D }); - | ------- ^ the trait `Copy` is not implemented for `B` + | ------- ^ the trait `Copy` is not implemented for `B<_>` | | | required by a bound introduced by this call | diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs index c8963e078f08a..cb78a78253392 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs +++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs @@ -36,7 +36,7 @@ trait Ty<'a> { fn main() { let v = Unit2.m( - L { //~ ERROR type mismatch + L { f: |x| { drop(x); Unit4 //~ ERROR to return `Unit3`, but it returns `Unit4` diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr index 4302570cdbdef..573f73dea7465 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr @@ -1,34 +1,3 @@ -error[E0271]: type mismatch resolving ` as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` - --> $DIR/issue-62203-hrtb-ice.rs:39:9 - | -LL | let v = Unit2.m( - | - required by a bound introduced by this call -LL | / L { -LL | | f: |x| { -LL | | drop(x); -LL | | Unit4 -LL | | }, -LL | | }, - | |_________^ type mismatch resolving ` as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` - | -note: expected this to be `<_ as Ty<'_>>::V` - --> $DIR/issue-62203-hrtb-ice.rs:21:14 - | -LL | type O = T::Output; - | ^^^^^^^^^ - = note: expected associated type `<_ as Ty<'_>>::V` - found struct `Unit4` - = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -note: required by a bound in `T1::m` - --> $DIR/issue-62203-hrtb-ice.rs:27:51 - | -LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 - | - required by a bound in this associated function -LL | where -LL | F: for<'r> T0<'r, (>::V,), O = >::V>, - | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` - error[E0271]: expected `{closure@issue-62203-hrtb-ice.rs:40:16}` to return `Unit3`, but it returns `Unit4` --> $DIR/issue-62203-hrtb-ice.rs:42:17 | @@ -58,6 +27,6 @@ LL | where LL | F: for<'r> T0<'r, (>::V,), O = >::V>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/iterators/ranges.stderr b/tests/ui/iterators/ranges.stderr index f85ce644073ef..8f9373b9cd141 100644 --- a/tests/ui/iterators/ranges.stderr +++ b/tests/ui/iterators/ranges.stderr @@ -1,22 +1,22 @@ -error[E0277]: `RangeTo<{integer}>` is not an iterator +error[E0277]: `RangeTo<_>` is not an iterator --> $DIR/ranges.rs:2:14 | LL | for _ in ..10 {} | ^^^^ if you meant to iterate until a value, add a starting value | - = help: the trait `Iterator` is not implemented for `RangeTo<{integer}>` + = help: the trait `Iterator` is not implemented for `RangeTo<_>` = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end` - = note: required for `RangeTo<{integer}>` to implement `IntoIterator` + = note: required for `RangeTo<_>` to implement `IntoIterator` -error[E0277]: `std::ops::RangeToInclusive<{integer}>` is not an iterator +error[E0277]: `std::ops::RangeToInclusive<_>` is not an iterator --> $DIR/ranges.rs:4:14 | LL | for _ in ..=10 {} | ^^^^^ if you meant to iterate until a value (including it), add a starting value | - = help: the trait `Iterator` is not implemented for `std::ops::RangeToInclusive<{integer}>` + = help: the trait `Iterator` is not implemented for `std::ops::RangeToInclusive<_>` = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end` - = note: required for `std::ops::RangeToInclusive<{integer}>` to implement `IntoIterator` + = note: required for `std::ops::RangeToInclusive<_>` to implement `IntoIterator` error: aborting due to 2 previous errors diff --git a/tests/ui/wf/wf-const-type.rs b/tests/ui/wf/wf-const-type.rs index 3b770b4b91633..64b0d9c8de797 100644 --- a/tests/ui/wf/wf-const-type.rs +++ b/tests/ui/wf/wf-const-type.rs @@ -10,7 +10,6 @@ struct NotCopy; const FOO: IsCopy> = IsCopy { t: None }; //~^ ERROR E0277 //~| ERROR E0277 -//~| ERROR E0277 fn main() { } diff --git a/tests/ui/wf/wf-const-type.stderr b/tests/ui/wf/wf-const-type.stderr index dd6e97755bddd..039e907705ee6 100644 --- a/tests/ui/wf/wf-const-type.stderr +++ b/tests/ui/wf/wf-const-type.stderr @@ -16,25 +16,6 @@ LL + #[derive(Copy)] LL | struct NotCopy; | -error[E0277]: the trait bound `NotCopy: Copy` is not satisfied - --> $DIR/wf-const-type.rs:10:12 - | -LL | const FOO: IsCopy> = IsCopy { t: None }; - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy` - | - = note: required for `Option` to implement `Copy` -note: required by a bound in `IsCopy` - --> $DIR/wf-const-type.rs:7:17 - | -LL | struct IsCopy { t: T } - | ^^^^ required by this bound in `IsCopy` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider annotating `NotCopy` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct NotCopy; - | - error[E0277]: the trait bound `NotCopy: Copy` is not satisfied --> $DIR/wf-const-type.rs:10:50 | @@ -53,6 +34,6 @@ LL + #[derive(Copy)] LL | struct NotCopy; | -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.