From 86e1860495403ee0154608e51fe4b4d81203e15f Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Wed, 16 Feb 2022 15:48:46 +0000 Subject: [PATCH] Revert to inference variable based hidden type computation for RPIT --- .../rustc_infer/src/infer/opaque_types.rs | 2 +- compiler/rustc_typeck/src/check/check.rs | 45 ++++++++++- compiler/rustc_typeck/src/check/writeback.rs | 24 +++++- .../impl-trait-return-missing-constraint.rs | 3 +- ...mpl-trait-return-missing-constraint.stderr | 31 ++++++- .../async-await/issue-64130-4-async-move.rs | 2 +- .../issue-64130-4-async-move.stderr | 6 +- src/test/ui/async-await/issue-70818.rs | 2 +- src/test/ui/async-await/issue-70818.stderr | 8 +- .../async-await/issue-70935-complex-spans.rs | 2 +- .../issue-70935-complex-spans.stderr | 6 +- src/test/ui/conservative_impl_trait.stderr | 9 +-- .../defaults/rp_impl_trait_fail.rs | 9 ++- .../defaults/rp_impl_trait_fail.stderr | 64 ++++++++++++--- src/test/ui/generator/issue-88653.rs | 8 +- src/test/ui/generator/issue-88653.stderr | 28 +++++-- .../type-mismatch-signature-deduction.rs | 4 +- .../type-mismatch-signature-deduction.stderr | 36 ++++++--- .../issue-92096.migrate.stderr | 18 ++--- .../generic-associated-types/issue-92096.rs | 4 +- .../ui/impl-trait/bound-normalization-fail.rs | 6 +- .../bound-normalization-fail.stderr | 63 +++++++++++++-- .../impl-trait/cross-return-site-inference.rs | 45 +++++++++++ .../cross-return-site-inference.stderr | 26 ++++++ src/test/ui/impl-trait/divergence.rs | 13 +++ src/test/ui/impl-trait/equality.stderr | 5 +- src/test/ui/impl-trait/issues/issue-70877.rs | 2 +- .../ui/impl-trait/issues/issue-70877.stderr | 11 ++- .../ui/impl-trait/issues/issue-88236-2.rs | 4 +- .../ui/impl-trait/issues/issue-88236-2.stderr | 15 ++-- ...t_outlive_least_region_or_bound.nll.stderr | 2 +- .../must_outlive_least_region_or_bound.rs | 3 +- .../must_outlive_least_region_or_bound.stderr | 48 ++++++++--- .../ui/impl-trait/nested_impl_trait.stderr | 8 +- ...trait-in-return-position-impl-trait.stderr | 10 +-- ...-to-type-err-cause-on-impl-trait-return.rs | 12 +-- ...type-err-cause-on-impl-trait-return.stderr | 81 +++++-------------- ...rojection-mismatch-in-impl-where-clause.rs | 2 +- ...ction-mismatch-in-impl-where-clause.stderr | 6 +- src/test/ui/impl-trait/question_mark.rs | 31 +++++-- .../type_parameters_captured.nll.stderr | 2 +- .../ui/impl-trait/type_parameters_captured.rs | 3 +- .../type_parameters_captured.stderr | 23 ++++-- src/test/ui/issues-71798.rs | 2 +- src/test/ui/issues-71798.stderr | 6 +- .../lang-item-missing-generator.stderr | 4 +- .../lifetime-elision-return-type-trait.rs | 3 +- .../lifetime-elision-return-type-trait.stderr | 19 ++++- .../impl-trait-return-trailing-semicolon.rs | 1 + ...mpl-trait-return-trailing-semicolon.stderr | 11 ++- src/test/ui/suggestions/issue-81098.rs | 2 + src/test/ui/suggestions/issue-81098.stderr | 27 ++++++- .../trait-object-nested-in-impl-trait.stderr | 52 ++++-------- .../nested-tait-inference.rs | 3 +- .../nested-tait-inference.stderr | 23 +++++- .../nested-tait-inference2.rs | 3 +- .../nested-tait-inference2.stderr | 23 +++++- 57 files changed, 642 insertions(+), 269 deletions(-) create mode 100644 src/test/ui/impl-trait/cross-return-site-inference.rs create mode 100644 src/test/ui/impl-trait/cross-return-site-inference.stderr create mode 100644 src/test/ui/impl-trait/divergence.rs diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index ba74aa804e3..ce922bca356 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -510,7 +510,7 @@ impl UseKind { impl<'a, 'tcx> InferCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] - fn register_hidden_type( + pub fn register_hidden_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, cause: ObligationCause<'tcx>, diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 1a5f118ea50..ee93a8ce535 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -3,6 +3,7 @@ use super::compare_method::check_type_bounds; use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl}; use super::*; +use hir::OpaqueTyOrigin; use rustc_attr as attr; use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_hir as hir; @@ -12,8 +13,9 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{def::Res, ItemKind, Node, PathSegment}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; +use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::fold::TypeFoldable; +use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; @@ -95,7 +97,46 @@ pub(super) fn check_fn<'a, 'tcx>( let declared_ret_ty = fn_sig.output(); - fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(declared_ret_ty))); + let ret_ty = declared_ret_ty.fold_with(&mut BottomUpFolder { + tcx: fcx.tcx, + ty_op: |ty| match *ty.kind() { + ty::Opaque(def_id, substs) => { + let span = tcx.def_span(def_id); + if let Some(origin @ OpaqueTyOrigin::FnReturn(_)) = + fcx.infcx.opaque_type_origin(def_id, span) + { + let hidden_ty = fcx.infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: span, + }); + + let cause = ObligationCause::misc(span, body.value.hir_id); + match fcx.infcx.register_hidden_type( + ty::OpaqueTypeKey { def_id, substs }, + cause.clone(), + param_env, + hidden_ty, + origin, + ) { + Ok(infer_ok) => { + fcx.register_infer_ok_obligations(infer_ok); + hidden_ty + } + Err(err) => { + fcx.report_mismatched_types(&cause, ty, hidden_ty, err).emit(); + tcx.ty_error() + } + } + } else { + ty + } + } + _ => ty, + }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }); + fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); fcx.ret_type_span = Some(decl.output.span()); let span = body.value.span; diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 35f1ddb65aa..ecbd1e46349 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -20,6 +20,7 @@ use rustc_span::symbol::sym; use rustc_span::Span; use std::mem; +use std::ops::ControlFlow; /////////////////////////////////////////////////////////////////////////// // Entry point @@ -503,7 +504,28 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { for (opaque_type_key, decl) in opaque_types { let hidden_type = match decl.origin { hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => { - Some(self.resolve(decl.hidden_type.ty, &decl.hidden_type.span)) + let ty = self.resolve(decl.hidden_type.ty, &decl.hidden_type.span); + struct RecursionChecker { + def_id: DefId, + } + impl<'tcx> ty::TypeVisitor<'tcx> for RecursionChecker { + type BreakTy = (); + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { + if let ty::Opaque(def_id, _) = *t.kind() { + if def_id == self.def_id { + return ControlFlow::Break(()); + } + } + t.super_visit_with(self) + } + } + if ty + .visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id }) + .is_break() + { + return; + } + Some(ty) } hir::OpaqueTyOrigin::TyAlias => None, }; diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs index 30e4c1a3c53..ef0443034ec 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs @@ -23,8 +23,9 @@ fn bar() -> impl Bar { } fn baz() -> impl Bar<Item = i32> { - bar() //~^ ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32` + //~| ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32` + bar() } fn main() { diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr index 9523a54d954..b7c49570ca4 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr @@ -1,11 +1,11 @@ error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32` - --> $DIR/impl-trait-return-missing-constraint.rs:26:5 + --> $DIR/impl-trait-return-missing-constraint.rs:25:13 | LL | fn bar() -> impl Bar { | -------- the expected opaque type ... -LL | bar() - | ^^^^^ expected associated type, found `i32` +LL | fn baz() -> impl Bar<Item = i32> { + | ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32` | = note: expected associated type `<impl Bar as Foo>::Item` found type `i32` @@ -16,6 +16,29 @@ help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i3 LL | fn bar() -> impl Bar<Item = i32> { | ++++++++++++ -error: aborting due to previous error +error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32` + --> $DIR/impl-trait-return-missing-constraint.rs:25:34 + | +LL | fn bar() -> impl Bar { + | -------- the expected opaque type +... +LL | fn baz() -> impl Bar<Item = i32> { + | __________________________________^ +LL | | +LL | | +LL | | bar() +LL | | } + | |_^ expected associated type, found `i32` + | + = note: expected associated type `<impl Bar as Foo>::Item` + found type `i32` + = help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` or calling a method that returns `<impl Bar as Foo>::Item` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` + | +LL | fn bar() -> impl Bar<Item = i32> { + | ++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/async-await/issue-64130-4-async-move.rs b/src/test/ui/async-await/issue-64130-4-async-move.rs index 7cb02e5cf38..2538f34351e 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.rs +++ b/src/test/ui/async-await/issue-64130-4-async-move.rs @@ -13,9 +13,9 @@ impl Client { async fn get() { } pub fn foo() -> impl Future + Send { + //~^ ERROR future cannot be sent between threads safely let client = Client(Box::new(true)); async move { - //~^ ERROR future cannot be sent between threads safely match client.status() { 200 => { let _x = get().await; diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index 3a84907e0c0..d631e6dc7f7 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-64130-4-async-move.rs:17:5 + --> $DIR/issue-64130-4-async-move.rs:15:17 | -LL | async move { - | ^^^^^^^^^^ future created by async block is not `Send` +LL | pub fn foo() -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-70818.rs b/src/test/ui/async-await/issue-70818.rs index 631389e10f3..019c56eb2fa 100644 --- a/src/test/ui/async-await/issue-70818.rs +++ b/src/test/ui/async-await/issue-70818.rs @@ -2,8 +2,8 @@ use std::future::Future; fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send { - async { (ty, ty1) } //~^ Error future cannot be sent between threads safely + async { (ty, ty1) } } fn main() {} diff --git a/src/test/ui/async-await/issue-70818.stderr b/src/test/ui/async-await/issue-70818.stderr index cb50c70f998..20109d4d116 100644 --- a/src/test/ui/async-await/issue-70818.stderr +++ b/src/test/ui/async-await/issue-70818.stderr @@ -1,11 +1,11 @@ error: future cannot be sent between threads safely - --> $DIR/issue-70818.rs:5:5 + --> $DIR/issue-70818.rs:4:38 | -LL | async { (ty, ty1) } - | ^^^^^ future created by async block is not `Send` +LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | note: captured value is not `Send` - --> $DIR/issue-70818.rs:5:18 + --> $DIR/issue-70818.rs:6:18 | LL | async { (ty, ty1) } | ^^^ has type `U` which is not `Send` diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs index 49456122951..2965a7e0654 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.rs +++ b/src/test/ui/async-await/issue-70935-complex-spans.rs @@ -8,8 +8,8 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> { } fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send { + //~^ ERROR: future cannot be sent between threads safely async move { - //~^ ERROR: future cannot be sent between threads safely baz(|| async{ foo(tx.clone()); }).await; diff --git a/src/test/ui/async-await/issue-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.stderr index ad61f21741b..db309938119 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-70935-complex-spans.rs:11:5 + --> $DIR/issue-70935-complex-spans.rs:10:45 | -LL | async move { - | ^^^^^^^^^^ future created by async block is not `Send` +LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `Sender<i32>` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr index 9dc486980aa..63a4df242f8 100644 --- a/src/test/ui/conservative_impl_trait.stderr +++ b/src/test/ui/conservative_impl_trait.stderr @@ -1,11 +1,8 @@ error[E0277]: `()` is not an iterator - --> $DIR/conservative_impl_trait.rs:3:60 + --> $DIR/conservative_impl_trait.rs:3:33 | -LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> { - | ____________________________________________________________^ -LL | | -LL | | } - | |_^ `()` is not an iterator +LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `Iterator` is not implemented for `()` diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs index b3bd88ad7d5..24031aa1e61 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -4,8 +4,9 @@ trait Trait {} impl<const N: u32> Trait for Uwu<N> {} fn rawr() -> impl Trait { - Uwu::<10, 12> //~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied + //~| error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied + Uwu::<10, 12> } trait Traitor<const N: u8 = 1, const M: u8 = N> { } @@ -15,13 +16,15 @@ impl Traitor<1, 2> for u64 {} fn uwu<const N: u8>() -> impl Traitor<N> { - 1_u32 //~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied + //~| error: the trait bound `u32: Traitor<N, N>` is not satisfied + 1_u32 } fn owo() -> impl Traitor { - 1_u64 //~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied + //~| error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied + 1_u64 } fn main() { diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 1cfaf83c5a6..81cfcb35606 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -1,32 +1,76 @@ error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:7:5 + --> $DIR/rp_impl_trait_fail.rs:6:14 | -LL | Uwu::<10, 12> - | ^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` +LL | fn rawr() -> impl Trait { + | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` + | + = help: the following implementations were found: + <Uwu<N> as Trait> + +error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied + --> $DIR/rp_impl_trait_fail.rs:6:25 + | +LL | fn rawr() -> impl Trait { + | _________________________^ +LL | | +LL | | +LL | | Uwu::<10, 12> +LL | | } + | |_^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` | = help: the following implementations were found: <Uwu<N> as Trait> error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:18:5 + --> $DIR/rp_impl_trait_fail.rs:18:26 | -LL | 1_u32 - | ^^^^^ the trait `Traitor<N, N>` is not implemented for `u32` +LL | fn uwu<const N: u8>() -> impl Traitor<N> { + | ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32` + | + = help: the following implementations were found: + <u32 as Traitor<N, 2_u8>> + <u64 as Traitor<1_u8, 2_u8>> + +error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied + --> $DIR/rp_impl_trait_fail.rs:18:42 + | +LL | fn uwu<const N: u8>() -> impl Traitor<N> { + | __________________________________________^ +LL | | +LL | | +LL | | 1_u32 +LL | | } + | |_^ the trait `Traitor<N, N>` is not implemented for `u32` | = help: the following implementations were found: <u32 as Traitor<N, 2_u8>> <u64 as Traitor<1_u8, 2_u8>> error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:23:5 + --> $DIR/rp_impl_trait_fail.rs:24:13 | -LL | 1_u64 - | ^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` +LL | fn owo() -> impl Traitor { + | ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` | = help: the following implementations were found: <u64 as Traitor<1_u8, 2_u8>> <u32 as Traitor<N, 2_u8>> -error: aborting due to 3 previous errors +error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied + --> $DIR/rp_impl_trait_fail.rs:24:26 + | +LL | fn owo() -> impl Traitor { + | __________________________^ +LL | | +LL | | +LL | | 1_u64 +LL | | } + | |_^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` + | + = help: the following implementations were found: + <u64 as Traitor<1_u8, 2_u8>> + <u32 as Traitor<N, 2_u8>> + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/issue-88653.rs b/src/test/ui/generator/issue-88653.rs index c4905995a86..f27956e4595 100644 --- a/src/test/ui/generator/issue-88653.rs +++ b/src/test/ui/generator/issue-88653.rs @@ -6,10 +6,14 @@ use std::ops::Generator; fn foo(bar: bool) -> impl Generator<(bool,)> { - |bar| { - //~^ NOTE: found signature of `fn(bool) -> _` + //~^ ERROR: type mismatch in generator arguments [E0631] //~| ERROR: type mismatch in generator arguments [E0631] //~| NOTE: expected signature of `fn((bool,)) -> _` + //~| NOTE: expected signature of `fn((bool,)) -> _` + //~| NOTE: in this expansion of desugaring of `impl Trait` + |bar| { + //~^ NOTE: found signature of `fn(bool) -> _` + //~| NOTE: found signature of `fn(bool) -> _` if bar { yield bar; } diff --git a/src/test/ui/generator/issue-88653.stderr b/src/test/ui/generator/issue-88653.stderr index eaa90a8e60a..25357411ce1 100644 --- a/src/test/ui/generator/issue-88653.stderr +++ b/src/test/ui/generator/issue-88653.stderr @@ -1,12 +1,28 @@ error[E0631]: type mismatch in generator arguments - --> $DIR/issue-88653.rs:9:5 + --> $DIR/issue-88653.rs:8:22 | +LL | fn foo(bar: bool) -> impl Generator<(bool,)> { + | ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _` +... LL | |bar| { - | ^^^^^ - | | - | expected signature of `fn((bool,)) -> _` - | found signature of `fn(bool) -> _` + | ----- found signature of `fn(bool) -> _` -error: aborting due to previous error +error[E0631]: type mismatch in generator arguments + --> $DIR/issue-88653.rs:8:46 + | +LL | fn foo(bar: bool) -> impl Generator<(bool,)> { + | ______________________________________________^ +LL | | +LL | | +LL | | +... | +LL | | |bar| { + | | ----- found signature of `fn(bool) -> _` +... | +LL | | } +LL | | } + | |_^ expected signature of `fn((bool,)) -> _` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.rs b/src/test/ui/generator/type-mismatch-signature-deduction.rs index d1b16b6e10d..77b830783c3 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.rs +++ b/src/test/ui/generator/type-mismatch-signature-deduction.rs @@ -3,7 +3,9 @@ use std::ops::Generator; fn foo() -> impl Generator<Return = i32> { - || { //~ ERROR type mismatch + //~^ ERROR type mismatch + //~| ERROR type mismatch + || { if false { return Ok(6); } diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr index 3e78e5b53ba..6369e7ec4c7 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr +++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-mismatch-signature-deduction.rs:13:9 + --> $DIR/type-mismatch-signature-deduction.rs:15:9 | LL | 5 | ^ expected enum `Result`, found integer @@ -7,27 +7,37 @@ LL | 5 = note: expected type `Result<{integer}, _>` found type `{integer}` note: return type inferred to be `Result<{integer}, _>` here - --> $DIR/type-mismatch-signature-deduction.rs:8:20 + --> $DIR/type-mismatch-signature-deduction.rs:10:20 | LL | return Ok(6); | ^^^^^ -error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6] as Generator>::Return == i32` - --> $DIR/type-mismatch-signature-deduction.rs:6:5 +error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:8:5: 16:6] as Generator>::Return == i32` + --> $DIR/type-mismatch-signature-deduction.rs:5:13 | -LL | / || { -LL | | if false { -LL | | return Ok(6); -LL | | } -... | -LL | | 5 -LL | | } - | |_____^ expected enum `Result`, found `i32` +LL | fn foo() -> impl Generator<Return = i32> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `i32` | = note: expected enum `Result<{integer}, _>` found type `i32` -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:8:5: 16:6] as Generator>::Return == i32` + --> $DIR/type-mismatch-signature-deduction.rs:5:42 + | +LL | fn foo() -> impl Generator<Return = i32> { + | __________________________________________^ +LL | | +LL | | +LL | | || { +... | +LL | | } +LL | | } + | |_^ expected enum `Result`, found `i32` + | + = note: expected enum `Result<{integer}, _>` + found type `i32` + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr index f8c89829e16..72ade5774d7 100644 --- a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr +++ b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr @@ -1,20 +1,18 @@ error[E0311]: the parameter type `C` may not live long enough - --> $DIR/issue-92096.rs:24:5 + --> $DIR/issue-92096.rs:20:33 | LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send - | - help: consider adding an explicit lifetime bound...: `C: 'a` -... -LL | async move { c.connect().await } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `C: 'a` error[E0311]: the parameter type `C` may not live long enough - --> $DIR/issue-92096.rs:24:5 + --> $DIR/issue-92096.rs:20:33 | LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send - | - help: consider adding an explicit lifetime bound...: `C: 'a` -... -LL | async move { c.connect().await } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `C: 'a` error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-92096.rs b/src/test/ui/generic-associated-types/issue-92096.rs index 2bc1af5506f..066132a5d98 100644 --- a/src/test/ui/generic-associated-types/issue-92096.rs +++ b/src/test/ui/generic-associated-types/issue-92096.rs @@ -18,12 +18,12 @@ trait Client { } fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send +//[migrate]~^ ERROR the parameter +//[migrate]~| ERROR the parameter where C: Client + Send + Sync, { async move { c.connect().await } - //[migrate]~^ ERROR the parameter - //[migrate]~| ERROR the parameter } fn main() {} diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index 20ddad0547e..9f962fa9bba 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -23,8 +23,9 @@ mod impl_trait { /// `T::Assoc` can't be normalized any further here. fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { - Foo(()) //~^ ERROR: type mismatch + //~| ERROR: type mismatch + Foo(()) } } @@ -40,8 +41,9 @@ mod lifetimes { /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + //~| ERROR: type mismatch + //~| ERROR: type mismatch Foo(()) - //~^ ERROR: type mismatch } } diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 01fb853e1d1..0344f416eb7 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,8 +1,31 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` - --> $DIR/bound-normalization-fail.rs:26:9 + --> $DIR/bound-normalization-fail.rs:25:32 | -LL | Foo(()) - | ^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` +LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` + | +note: expected this to be `()` + --> $DIR/bound-normalization-fail.rs:14:19 + | +LL | type Output = T; + | ^ + = note: expected unit type `()` + found associated type `<T as impl_trait::Trait>::Assoc` +help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()` + | +LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { + | ++++++++++++ + +error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` + --> $DIR/bound-normalization-fail.rs:25:64 + | +LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { + | ________________________________________________________________^ +LL | | +LL | | +LL | | Foo(()) +LL | | } + | |_____^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` | note: expected this to be `()` --> $DIR/bound-normalization-fail.rs:14:19 @@ -17,16 +40,16 @@ LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> | ++++++++++++ error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/bound-normalization-fail.rs:41:41 + --> $DIR/bound-normalization-fail.rs:42:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` - --> $DIR/bound-normalization-fail.rs:43:9 + --> $DIR/bound-normalization-fail.rs:42:41 | -LL | Foo(()) - | ^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` +LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` | note: expected this to be `()` --> $DIR/bound-normalization-fail.rs:14:19 @@ -40,7 +63,31 @@ help: consider constraining the associated type `<T as lifetimes::Trait<'static> LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { | ++++++++++++ -error: aborting due to 3 previous errors +error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` + --> $DIR/bound-normalization-fail.rs:42:73 + | +LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { + | _________________________________________________________________________^ +LL | | +LL | | +LL | | +LL | | Foo(()) +LL | | } + | |_____^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` + | +note: expected this to be `()` + --> $DIR/bound-normalization-fail.rs:14:19 + | +LL | type Output = T; + | ^ + = note: expected unit type `()` + found associated type `<T as lifetimes::Trait<'static>>::Assoc` +help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()` + | +LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { + | ++++++++++++ + +error: aborting due to 5 previous errors Some errors have detailed explanations: E0271, E0760. For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/impl-trait/cross-return-site-inference.rs b/src/test/ui/impl-trait/cross-return-site-inference.rs new file mode 100644 index 00000000000..ceb8414650f --- /dev/null +++ b/src/test/ui/impl-trait/cross-return-site-inference.rs @@ -0,0 +1,45 @@ +// edition:2021 + +fn foo(b: bool) -> impl std::fmt::Debug { + if b { + return vec![42] + } + [].into_iter().collect() +} + +fn bar(b: bool) -> impl std::fmt::Debug { + if b { + return [].into_iter().collect() + } + vec![42] +} + +fn bak(b: bool) -> impl std::fmt::Debug { + if b { + return std::iter::empty().collect() + } + vec![42] +} + +fn baa(b: bool) -> impl std::fmt::Debug { + if b { + return [42].into_iter().collect() + } + vec![] +} + +fn muh() -> Result<(), impl std::fmt::Debug> { + Err("whoops")?; //~ ERROR `?` couldn't convert the error to `impl Debug` + Ok(()) +} + +fn muh2() -> Result<(), impl std::fmt::Debug> { + return Err(From::from("foo")); //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied + Ok(()) +} + +fn muh3() -> Result<(), impl std::fmt::Debug> { + Err(From::from("foo")) //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied +} + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/impl-trait/cross-return-site-inference.stderr b/src/test/ui/impl-trait/cross-return-site-inference.stderr new file mode 100644 index 00000000000..06afb938c5f --- /dev/null +++ b/src/test/ui/impl-trait/cross-return-site-inference.stderr @@ -0,0 +1,26 @@ +error[E0277]: `?` couldn't convert the error to `impl Debug` + --> $DIR/cross-return-site-inference.rs:32:18 + | +LL | fn muh() -> Result<(), impl std::fmt::Debug> { + | -------------------------------- expected `impl Debug` because of this +LL | Err("whoops")?; + | ^ the trait `From<&str>` is not implemented for `impl Debug` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<(), impl Debug>` + +error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied + --> $DIR/cross-return-site-inference.rs:37:16 + | +LL | return Err(From::from("foo")); + | ^^^^^^^^^^ the trait `From<&str>` is not implemented for `impl Debug` + +error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied + --> $DIR/cross-return-site-inference.rs:42:9 + | +LL | Err(From::from("foo")) + | ^^^^^^^^^^ the trait `From<&str>` is not implemented for `impl Debug` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/divergence.rs b/src/test/ui/impl-trait/divergence.rs new file mode 100644 index 00000000000..211f7972dbc --- /dev/null +++ b/src/test/ui/impl-trait/divergence.rs @@ -0,0 +1,13 @@ +// check-pass + +fn foo() -> impl MyTrait { + panic!(); + MyStruct +} + +struct MyStruct; +trait MyTrait {} + +impl MyTrait for MyStruct {} + +fn main() {} diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 185a3f53f65..804ccbcc6c0 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,13 +12,10 @@ error[E0308]: mismatched types --> $DIR/equality.rs:15:5 | LL | fn two(x: bool) -> impl Foo { - | -------- the expected opaque type + | -------- expected `_` because of return type ... LL | 0_u32 | ^^^^^ expected `i32`, found `u32` - | - = note: expected opaque type `impl Foo` - found type `u32` error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/impl-trait/issues/issue-70877.rs b/src/test/ui/impl-trait/issues/issue-70877.rs index 1a86fa00ed1..9cbe33aef5b 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.rs +++ b/src/test/ui/impl-trait/issues/issue-70877.rs @@ -28,7 +28,7 @@ fn ham() -> Foo { fn oof() -> impl std::fmt::Debug { let mut bar = ham(); let func = bar.next().unwrap(); - return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type + return func(&"oof"); //~^^^ ERROR opaque type's hidden type cannot be another opaque type } fn main() { diff --git a/src/test/ui/impl-trait/issues/issue-70877.stderr b/src/test/ui/impl-trait/issues/issue-70877.stderr index 7cbd58bdabf..2610a198186 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.stderr +++ b/src/test/ui/impl-trait/issues/issue-70877.stderr @@ -13,10 +13,15 @@ LL | Some(Box::new(quux)) found enum `Option<Box<for<'r> fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>` error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/issue-70877.rs:31:12 + --> $DIR/issue-70877.rs:28:34 | -LL | return func(&"oof"); - | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope +LL | fn oof() -> impl std::fmt::Debug { + | __________________________________^ +LL | | let mut bar = ham(); +LL | | let func = bar.next().unwrap(); +LL | | return func(&"oof"); +LL | | } + | |_^ one of the two opaque types used here has to be outside its defining scope | note: opaque type whose hidden type is being assigned --> $DIR/issue-70877.rs:28:13 diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs index f89ab7fbd36..af26a1f54c4 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.rs +++ b/src/test/ui/impl-trait/issues/issue-88236-2.rs @@ -14,10 +14,10 @@ impl<'a> Hrtb<'a> for &'a () { fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - &() //~ ERROR implementation of `Hrtb` is not general enough + &() //~^ ERROR implementation of `Hrtb` is not general enough } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - x //~ ERROR implementation of `Hrtb` is not general enough + x //~^ ERROR implementation of `Hrtb` is not general enough } fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr index 95c4a528036..45fadcab3f2 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr +++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr @@ -1,17 +1,20 @@ error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:17:5 + --> $DIR/issue-88236-2.rs:16:38 | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough +LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough | = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 + --> $DIR/issue-88236-2.rs:19:82 | -LL | x - | ^ implementation of `Hrtb` is not general enough +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | __________________________________________________________________________________^ +LL | | x +LL | | } + | |_^ implementation of `Hrtb` is not general enough | = note: `&()` must implement `Hrtb<'0>`, for any lifetime `'0`... = note: ...but `Hrtb<'_>` is actually implemented for the type `&()` diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index eb38f84d4af..9589b69491e 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -80,7 +80,7 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:39:5 + --> $DIR/must_outlive_least_region_or_bound.rs:41:5 | LL | x | ^ diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index 02ea0255912..baa42da6446 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -36,8 +36,9 @@ fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { } fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - x //~^ ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + x } fn main() {} diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 77ba0bf9087..1272adb35e9 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -28,10 +28,15 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ---- ^ ...is used and required to live as long as `'static` here + | ---- ^ ...is used here... | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:9:24 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } @@ -45,10 +50,15 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:11:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ------- ^ ...is used and required to live as long as `'static` here + | ------- ^ ...is used here... | | | this data with lifetime `'a`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:11:33 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -59,10 +69,10 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } | ~~~~~~~~~~~~ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:13:41 + --> $DIR/must_outlive_least_region_or_bound.rs:13:24 | LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } - | ---- ^ lifetime `'a` required + | ---- ^^^^^^^^^^^^^^ lifetime `'a` required | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` @@ -85,8 +95,13 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:29:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ------- this data with lifetime `'a`... ^ ...is used and required to live as long as `'static` here + | ------- this data with lifetime `'a`... ^ ...is used here... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:29:34 + | +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } @@ -110,12 +125,25 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:39:5 + --> $DIR/must_outlive_least_region_or_bound.rs:38:51 | LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - | -- help: consider adding an explicit lifetime bound...: `T: 'static +` -LL | x - | ^ ...so that the type `T` will meet its required lifetime bounds + | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `T: 'static +` + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:38:72 + | +LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { + | _________________________________--_____________________________________^ + | | | + | | help: consider adding an explicit lifetime bound...: `T: 'static +` +LL | | +LL | | +LL | | x +LL | | } + | |_^ ...so that the type `T` will meet its required lifetime bounds error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/must_outlive_least_region_or_bound.rs:16:50 @@ -203,7 +231,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) } | ~~~~~~~~~~~~ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors Some errors have detailed explanations: E0310, E0621, E0700, E0759. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr index a10e4ec3182..26b48c7cdf7 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.stderr +++ b/src/test/ui/impl-trait/nested_impl_trait.stderr @@ -47,18 +47,18 @@ LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> { | ^^^^^^^^^^^^^^ error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied - --> $DIR/nested_impl_trait.rs:5:70 + --> $DIR/nested_impl_trait.rs:5:46 | LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } - | ^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` | = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>` error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied - --> $DIR/nested_impl_trait.rs:18:58 + --> $DIR/nested_impl_trait.rs:18:34 | LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } - | ^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` | = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>` diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr index b2f7166f0ae..5ca01a59376 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr @@ -2,25 +2,19 @@ error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5 | LL | fn can() -> impl NotObjectSafe { - | ------------------ the expected opaque type + | ------------------ expected `_` because of return type ... LL | B | ^ expected struct `A`, found struct `B` - | - = note: expected opaque type `impl NotObjectSafe` - found struct `B` error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5 | LL | fn cat() -> impl ObjectSafe { - | --------------- the expected opaque type + | --------------- expected `_` because of return type ... LL | B | ^ expected struct `A`, found struct `B` - | - = note: expected opaque type `impl ObjectSafe` - found struct `B` error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs index 9f9a6c784e6..fa7664a83ee 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs @@ -14,10 +14,10 @@ fn bar() -> impl std::fmt::Display { } fn baz() -> impl std::fmt::Display { - if false { //~ ERROR mismatched types + if false { return 0i32; } else { - 1u32 + 1u32 //~ ERROR mismatched types } } @@ -30,9 +30,9 @@ fn qux() -> impl std::fmt::Display { } fn bat() -> impl std::fmt::Display { - match 13 { //~ ERROR mismatched types + match 13 { 0 => return 0i32, - _ => 1u32, + _ => 1u32, //~ ERROR mismatched types } } @@ -45,12 +45,12 @@ fn can() -> impl std::fmt::Display { } fn cat() -> impl std::fmt::Display { - match 13 { //~ ERROR mismatched types + match 13 { 0 => { return 0i32; } _ => { - 1u32 + 1u32 //~ ERROR mismatched types } } } diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr index db0d446e559..0c595f441ba 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr @@ -2,40 +2,28 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 | LL | fn foo() -> impl std::fmt::Display { - | ---------------------- the expected opaque type + | ---------------------- expected `_` because of return type ... LL | 1u32 | ^^^^ expected `i32`, found `u32` - | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16 | LL | fn bar() -> impl std::fmt::Display { - | ---------------------- the expected opaque type + | ---------------------- expected `_` because of return type ... LL | return 1u32; | ^^^^ expected `i32`, found `u32` - | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:17:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9 | -LL | fn baz() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -LL | / if false { -LL | | return 0i32; -LL | | } else { -LL | | 1u32 -LL | | } - | |_____^ expected `i32`, found `u32` - | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` +LL | fn baz() -> impl std::fmt::Display { + | ---------------------- expected `_` because of return type +... +LL | 1u32 + | ^^^^ expected `i32`, found `u32` error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9 @@ -48,63 +36,36 @@ LL | | 1u32 | | ^^^^ expected `i32`, found `u32` LL | | } | |_____- `if` and `else` have incompatible types - | -help: you could change the return type to be a boxed trait object - | -LL | fn qux() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ Box::new(0i32) -LL | } else { -LL ~ Box::new(1u32) - | error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:33:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14 | -LL | fn bat() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -LL | / match 13 { -LL | | 0 => return 0i32, -LL | | _ => 1u32, -LL | | } - | |_____^ expected `i32`, found `u32` - | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` +LL | fn bat() -> impl std::fmt::Display { + | ---------------------- expected `_` because of return type +... +LL | _ => 1u32, + | ^^^^ expected `i32`, found `u32` error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5 | LL | fn can() -> impl std::fmt::Display { - | ---------------------- the expected opaque type + | ---------------------- expected `_` because of return type LL | / match 13 { LL | | 0 => return 0i32, LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` - | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:48:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13 | -LL | fn cat() -> impl std::fmt::Display { - | ---------------------- the expected opaque type -LL | / match 13 { -LL | | 0 => { -LL | | return 0i32; -LL | | } -... | -LL | | } -LL | | } - | |_____^ expected `i32`, found `u32` - | - = note: expected opaque type `impl std::fmt::Display` - found type `u32` +LL | fn cat() -> impl std::fmt::Display { + | ---------------------- expected `_` because of return type +... +LL | 1u32 + | ^^^^ expected `i32`, found `u32` error[E0308]: `match` arms have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14 diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs index 2e7cb21592c..b4fd6b3e743 100644 --- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs @@ -11,8 +11,8 @@ pub trait Test {} impl<T> Test for T where T: Super<Assoc = ()> {} fn test() -> impl Test { - () //~^ERROR type mismatch resolving `<() as Super>::Assoc == ()` + () } fn main() { diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr index 5ef1e9abef6..ade0dfa1bb3 100644 --- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr @@ -1,8 +1,8 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()` - --> $DIR/projection-mismatch-in-impl-where-clause.rs:14:5 + --> $DIR/projection-mismatch-in-impl-where-clause.rs:13:14 | -LL | () - | ^^ type mismatch resolving `<() as Super>::Assoc == ()` +LL | fn test() -> impl Test { + | ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()` | note: expected this to be `u8` --> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18 diff --git a/src/test/ui/impl-trait/question_mark.rs b/src/test/ui/impl-trait/question_mark.rs index 211f7972dbc..495bf5c1d64 100644 --- a/src/test/ui/impl-trait/question_mark.rs +++ b/src/test/ui/impl-trait/question_mark.rs @@ -1,13 +1,30 @@ // check-pass -fn foo() -> impl MyTrait { - panic!(); - MyStruct +use std::fmt::Debug; + +#[derive(Debug)] +pub struct Target; + +#[derive(Debug)] +pub struct Source; +impl From<Source> for Target { + fn from(_: Source) -> Self { + Self + } } -struct MyStruct; -trait MyTrait {} +fn maybe_source() -> Result<(), Source> { + todo!() +} -impl MyTrait for MyStruct {} +pub fn typaram() -> Result<(), impl Debug> { + maybe_source()?; + Ok::<_, Target>(()) +} -fn main() {} +pub fn direct() -> Result<(), impl Debug> { + maybe_source()?; + Err(Target) +} + +fn main() {} \ No newline at end of file diff --git a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr index e0b77544d43..b1175a5952e 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr @@ -1,5 +1,5 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:8:5 + --> $DIR/type_parameters_captured.rs:10:5 | LL | x | ^ diff --git a/src/test/ui/impl-trait/type_parameters_captured.rs b/src/test/ui/impl-trait/type_parameters_captured.rs index 81ee7d3f8a5..bb9cab742a5 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.rs +++ b/src/test/ui/impl-trait/type_parameters_captured.rs @@ -5,8 +5,9 @@ impl<T> Any for T {} // Check that type parameters are captured and not considered 'static fn foo<T>(x: T) -> impl Any + 'static { - x //~^ ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + x } fn main() {} diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr index c0de4f4b4a0..c4ca34a6ed3 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.stderr @@ -1,11 +1,24 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:8:5 + --> $DIR/type_parameters_captured.rs:7:20 | LL | fn foo<T>(x: T) -> impl Any + 'static { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | x - | ^ ...so that the type `T` will meet its required lifetime bounds + | - ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | | + | help: consider adding an explicit lifetime bound...: `T: 'static` -error: aborting due to previous error +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/type_parameters_captured.rs:7:39 + | +LL | fn foo<T>(x: T) -> impl Any + 'static { + | ________-______________________________^ + | | | + | | help: consider adding an explicit lifetime bound...: `T: 'static` +LL | | +LL | | +LL | | x +LL | | } + | |_^ ...so that the type `T` will meet its required lifetime bounds + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs index 89e07037afd..14b6c0f3581 100644 --- a/src/test/ui/issues-71798.rs +++ b/src/test/ui/issues-71798.rs @@ -1,6 +1,6 @@ fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ { - *x //~^ ERROR `u32` is not a future + *x } fn main() { diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr index 1efa886436e..ab72c3e41af 100644 --- a/src/test/ui/issues-71798.stderr +++ b/src/test/ui/issues-71798.stderr @@ -5,10 +5,10 @@ LL | let _ = test_ref & u; | ^ not found in this scope error[E0277]: `u32` is not a future - --> $DIR/issues-71798.rs:2:5 + --> $DIR/issues-71798.rs:1:25 | -LL | *x - | ^^ `u32` is not a future +LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not a future | = help: the trait `Future` is not implemented for `u32` = note: u32 must be a future or must implement `IntoFuture` to be awaited diff --git a/src/test/ui/lang-items/lang-item-missing-generator.stderr b/src/test/ui/lang-items/lang-item-missing-generator.stderr index e5f26822f26..fa13bf0b127 100644 --- a/src/test/ui/lang-items/lang-item-missing-generator.stderr +++ b/src/test/ui/lang-items/lang-item-missing-generator.stderr @@ -1,8 +1,8 @@ error: requires `generator` lang_item - --> $DIR/lang-item-missing-generator.rs:15:22 + --> $DIR/lang-item-missing-generator.rs:15:17 | LL | pub fn abc() -> impl FnOnce(f32) { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs index fd49b4842a7..133679f30f8 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs @@ -6,8 +6,9 @@ trait Future { use std::error::Error; fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { - Ok(()) //~^ ERROR not satisfied + //~| ERROR not satisfied + Ok(()) } fn main() {} diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 7f8384d7eca..a3badd7b25a 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -1,9 +1,20 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied - --> $DIR/lifetime-elision-return-type-trait.rs:9:5 + --> $DIR/lifetime-elision-return-type-trait.rs:8:13 | -LL | Ok(()) - | ^^^^^^ the trait `Future` is not implemented for `Result<(), _>` +LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` -error: aborting due to previous error +error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied + --> $DIR/lifetime-elision-return-type-trait.rs:8:56 + | +LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { + | ________________________________________________________^ +LL | | +LL | | +LL | | Ok(()) +LL | | } + | |_^ the trait `Future` is not implemented for `Result<(), _>` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs index e72a2d8ccc6..cad7d76c6ab 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs @@ -2,6 +2,7 @@ trait Bar {} impl Bar for u8 {} fn foo() -> impl Bar { 5; //~^ ERROR the trait bound `(): Bar` is not satisfied + //~| ERROR the trait bound `(): Bar` is not satisfied } fn main() {} diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr index 07c1d8bccba..ba6967e78e1 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr @@ -1,12 +1,21 @@ +error[E0277]: the trait bound `(): Bar` is not satisfied + --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13 + | +LL | fn foo() -> impl Bar { + | ^^^^^^^^ the trait `Bar` is not implemented for `()` +LL | 5; + | - consider removing this semicolon + error[E0277]: the trait bound `(): Bar` is not satisfied --> $DIR/impl-trait-return-trailing-semicolon.rs:3:22 | LL | fn foo() -> impl Bar { | ______________________^ LL | | 5; +LL | | LL | | } | |_^ the trait `Bar` is not implemented for `()` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/issue-81098.rs b/src/test/ui/suggestions/issue-81098.rs index a601b5866f4..7ca7380a7be 100644 --- a/src/test/ui/suggestions/issue-81098.rs +++ b/src/test/ui/suggestions/issue-81098.rs @@ -1,12 +1,14 @@ // Don't suggest removing a semicolon if the last statement isn't an expression with semicolon // (#81098) fn wat() -> impl core::fmt::Display { //~ ERROR: `()` doesn't implement `std::fmt::Display` + //~^ ERROR: `()` doesn't implement `std::fmt::Display` fn why() {} } // Do it if the last statement is an expression with semicolon // (#54771) fn ok() -> impl core::fmt::Display { //~ ERROR: `()` doesn't implement `std::fmt::Display` + //~^ ERROR: `()` doesn't implement `std::fmt::Display` 1; } diff --git a/src/test/ui/suggestions/issue-81098.stderr b/src/test/ui/suggestions/issue-81098.stderr index f13e653cb06..d62526442e9 100644 --- a/src/test/ui/suggestions/issue-81098.stderr +++ b/src/test/ui/suggestions/issue-81098.stderr @@ -1,8 +1,18 @@ +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/issue-81098.rs:3:13 + | +LL | fn wat() -> impl core::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/issue-81098.rs:3:37 | LL | fn wat() -> impl core::fmt::Display { | _____________________________________^ +LL | | LL | | fn why() {} LL | | } | |_^ `()` cannot be formatted with the default formatter @@ -11,10 +21,23 @@ LL | | } = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-81098.rs:9:36 + --> $DIR/issue-81098.rs:10:12 + | +LL | fn ok() -> impl core::fmt::Display { + | ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter +LL | +LL | 1; + | - consider removing this semicolon + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/issue-81098.rs:10:36 | LL | fn ok() -> impl core::fmt::Display { | ____________________________________^ +LL | | LL | | 1; LL | | } | |_^ `()` cannot be formatted with the default formatter @@ -22,6 +45,6 @@ LL | | } = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr index c7f1215c8cc..a5b50634c71 100644 --- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr +++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr @@ -7,18 +7,13 @@ LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:27:23 | -LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ { @@ -37,18 +32,13 @@ LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:38:23 | -LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ { @@ -63,18 +53,13 @@ LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:49:30 | -LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a { @@ -89,18 +74,13 @@ LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is used and required to live as long as `'static` here + | ...is used here... | -note: `'static` lifetime requirement introduced by the return type +note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:60:30 | -LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type -LL | / Iter { -LL | | current: None, -LL | | remaining: self.0.iter(), -LL | | } - | |_________- because of this returned expression +LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a { diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs index 784a6c75886..314e5362a8f 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -10,9 +10,10 @@ trait Foo<A> { } impl Foo<()> for () { } fn foo() -> impl Foo<FooX> { + //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied + //~| ERROR: the trait bound `(): Foo<FooX>` is not satisfied // FIXME(type-alias-impl-trait): We could probably make this work. () - //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied } fn main() { } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr index 9472cac6355..eb72e887691 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr @@ -1,12 +1,27 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied - --> $DIR/nested-tait-inference.rs:14:5 + --> $DIR/nested-tait-inference.rs:12:13 | -LL | () - | ^^ the trait `Foo<FooX>` is not implemented for `()` +LL | fn foo() -> impl Foo<FooX> { + | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()` | = help: the following implementations were found: <() as Foo<()>> -error: aborting due to previous error +error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied + --> $DIR/nested-tait-inference.rs:12:28 + | +LL | fn foo() -> impl Foo<FooX> { + | ____________________________^ +LL | | +LL | | +LL | | // FIXME(type-alias-impl-trait): We could probably make this work. +LL | | () +LL | | } + | |_^ the trait `Foo<FooX>` is not implemented for `()` + | + = help: the following implementations were found: + <() as Foo<()>> + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs index 00bd44c493c..4dc30d9257b 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -11,8 +11,9 @@ impl Foo<()> for () {} impl Foo<u32> for () {} fn foo() -> impl Foo<FooX> { - () //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied + //~| ERROR: the trait bound `(): Foo<FooX>` is not satisfied + () } fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr index ec1b4642d08..1372a018667 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -1,13 +1,28 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied - --> $DIR/nested-tait-inference2.rs:14:5 + --> $DIR/nested-tait-inference2.rs:13:13 | -LL | () - | ^^ the trait `Foo<FooX>` is not implemented for `()` +LL | fn foo() -> impl Foo<FooX> { + | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()` | = help: the following implementations were found: <() as Foo<()>> <() as Foo<u32>> -error: aborting due to previous error +error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied + --> $DIR/nested-tait-inference2.rs:13:28 + | +LL | fn foo() -> impl Foo<FooX> { + | ____________________________^ +LL | | +LL | | +LL | | () +LL | | } + | |_^ the trait `Foo<FooX>` is not implemented for `()` + | + = help: the following implementations were found: + <() as Foo<()>> + <() as Foo<u32>> + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.