diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 8396e3263f9a4..5d17693dc0820 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1492,6 +1492,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } } } + ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => { + self.get_parent_trait_ref(&parent_code) + } _ => None, } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d602662ba6be4..2689e2134fc6b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1422,6 +1422,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { while let Some(code) = next_code { debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code); match code { + ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => { + next_code = Some(parent_code.as_ref()); + } ObligationCauseCode::DerivedObligation(derived_obligation) | ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) | ObligationCauseCode::ImplDerivedObligation(derived_obligation) => { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 551522334aa00..b3e18dab36369 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -370,6 +370,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise. let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty); + final_arg_types.push((i, checked_ty, coerce_ty)); + // Cause selection errors caused by resolving a single argument to point at the // argument and not the call. This is otherwise redundant with the `demand_coerce` // call immediately after, but it lets us customize the span pointed to in the @@ -377,38 +379,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let _ = self.resolve_vars_with_obligations_and_mutate_fulfillment( coerce_ty, |errors| { - // This is not coming from a macro or a `derive`. - if sp.desugaring_kind().is_none() - && !arg.span.from_expansion() - // Do not change the spans of `async fn`s. - && !matches!( - expr.kind, - hir::ExprKind::Call( - hir::Expr { - kind: hir::ExprKind::Path(hir::QPath::LangItem(_, _)), - .. - }, - _ - ) - ) { - for error in errors { - error.obligation.cause.make_mut().span = arg.span; - let code = error.obligation.cause.code.clone(); - error.obligation.cause.make_mut().code = - ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id: arg.hir_id, - call_hir_id: expr.hir_id, - parent_code: Lrc::new(code), - }; - } - } + self.point_at_type_arg_instead_of_call_if_possible(errors, expr); + self.point_at_arg_instead_of_call_if_possible( + errors, + &final_arg_types, + expr, + sp, + args, + ); }, ); // We're processing function arguments so we definitely want to use // two-phase borrows. self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes); - final_arg_types.push((i, checked_ty, coerce_ty)); // 3. Relate the expected type and the formal one, // if the expected type was used for the coercion. @@ -973,45 +957,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - if let ty::PredicateKind::Trait(predicate) = - error.obligation.predicate.kind().skip_binder() - { - // Collect the argument position for all arguments that could have caused this - // `FulfillmentError`. - let mut referenced_in = final_arg_types - .iter() - .map(|&(i, checked_ty, _)| (i, checked_ty)) - .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty))) - .flat_map(|(i, ty)| { - let ty = self.resolve_vars_if_possible(ty); - // We walk the argument type because the argument's type could have - // been `Option`, but the `FulfillmentError` references `T`. - if ty.walk(self.tcx).any(|arg| arg == predicate.self_ty().into()) { - Some(i) - } else { - None - } - }) - .collect::>(); - - // Both checked and coerced types could have matched, thus we need to remove - // duplicates. - - // We sort primitive type usize here and can use unstable sort - referenced_in.sort_unstable(); - referenced_in.dedup(); - - if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) { - // We make sure that only *one* argument matches the obligation failure - // and we assign the obligation's span to its expression's. - error.obligation.cause.make_mut().span = args[ref_in].span; - let code = error.obligation.cause.code.clone(); - error.obligation.cause.make_mut().code = - ObligationCauseCode::FunctionArgumentObligation { - arg_hir_id: args[ref_in].hir_id, - call_hir_id: expr.hir_id, - parent_code: Lrc::new(code), - }; + // Peel derived obligation, because it's the type that originally + // started this inference chain that matters, not the one we wound + // up with at the end. + fn unpeel_to_top( + mut code: Lrc>, + ) -> Lrc> { + let mut result_code = code.clone(); + loop { + let parent = match &*code { + ObligationCauseCode::BuiltinDerivedObligation(c) + | ObligationCauseCode::ImplDerivedObligation(c) + | ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(), + _ => break, + }; + result_code = std::mem::replace(&mut code, parent); + } + result_code + } + let self_: ty::subst::GenericArg<'_> = match &*unpeel_to_top(Lrc::new(error.obligation.cause.code.clone())) { + ObligationCauseCode::BuiltinDerivedObligation(code) | + ObligationCauseCode::ImplDerivedObligation(code) | + ObligationCauseCode::DerivedObligation(code) => { + code.parent_trait_ref.self_ty().skip_binder().into() + } + _ if let ty::PredicateKind::Trait(predicate) = + error.obligation.predicate.kind().skip_binder() => { + predicate.self_ty().into() + } + _ => continue, + }; + let self_ = self.resolve_vars_if_possible(self_); + + // Collect the argument position for all arguments that could have caused this + // `FulfillmentError`. + let mut referenced_in = final_arg_types + .iter() + .map(|&(i, checked_ty, _)| (i, checked_ty)) + .chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty))) + .flat_map(|(i, ty)| { + let ty = self.resolve_vars_if_possible(ty); + // We walk the argument type because the argument's type could have + // been `Option`, but the `FulfillmentError` references `T`. + if ty.walk(self.tcx).any(|arg| arg == self_) { Some(i) } else { None } + }) + .collect::>(); + + // Both checked and coerced types could have matched, thus we need to remove + // duplicates. + + // We sort primitive type usize here and can use unstable sort + referenced_in.sort_unstable(); + referenced_in.dedup(); + + if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) { + // Do not point at the inside of a macro. + // That would often result in poor error messages. + if args[ref_in].span.from_expansion() { + return; + } + // We make sure that only *one* argument matches the obligation failure + // and we assign the obligation's span to its expression's. + error.obligation.cause.make_mut().span = args[ref_in].span; + let code = error.obligation.cause.code.clone(); + error.obligation.cause.make_mut().code = + ObligationCauseCode::FunctionArgumentObligation { + arg_hir_id: args[ref_in].hir_id, + call_hir_id: expr.hir_id, + parent_code: Lrc::new(code), + }; + } else if error.obligation.cause.make_mut().span == call_sp { + // Make function calls point at the callee, not the whole thing. + if let hir::ExprKind::Call(callee, _) = expr.kind { + error.obligation.cause.make_mut().span = callee.span; } } } diff --git a/src/test/ui/associated-types/associated-types-path-2.rs b/src/test/ui/associated-types/associated-types-path-2.rs index 912dedfdcebbc..c993e1d27202d 100644 --- a/src/test/ui/associated-types/associated-types-path-2.rs +++ b/src/test/ui/associated-types/associated-types-path-2.rs @@ -28,11 +28,13 @@ pub fn f1_int_uint() { pub fn f1_uint_uint() { f1(2u32, 4u32); //~^ ERROR `u32: Foo` is not satisfied + //~| ERROR `u32: Foo` is not satisfied } pub fn f1_uint_int() { f1(2u32, 4i32); //~^ ERROR `u32: Foo` is not satisfied + //~| ERROR `u32: Foo` is not satisfied } pub fn f2_int() { diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 15a5245d54d95..b3bb58f78142a 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -10,12 +10,10 @@ LL | f1(2i32, 4u32); | ~~~ error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:14 + --> $DIR/associated-types-path-2.rs:29:5 | LL | f1(2u32, 4u32); - | -- ^^^^ the trait `Foo` is not implemented for `u32` - | | - | required by a bound introduced by this call + | ^^ the trait `Foo` is not implemented for `u32` | note: required by a bound in `f1` --> $DIR/associated-types-path-2.rs:13:14 @@ -24,10 +22,16 @@ LL | pub fn f1(a: T, x: T::A) {} | ^^^ required by this bound in `f1` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:34:14 + --> $DIR/associated-types-path-2.rs:29:14 + | +LL | f1(2u32, 4u32); + | ^^^^ the trait `Foo` is not implemented for `u32` + +error[E0277]: the trait bound `u32: Foo` is not satisfied + --> $DIR/associated-types-path-2.rs:35:8 | LL | f1(2u32, 4i32); - | -- ^^^^ the trait `Foo` is not implemented for `u32` + | -- ^^^^ the trait `Foo` is not implemented for `u32` | | | required by a bound introduced by this call | @@ -37,8 +41,14 @@ note: required by a bound in `f1` LL | pub fn f1(a: T, x: T::A) {} | ^^^ required by this bound in `f1` +error[E0277]: the trait bound `u32: Foo` is not satisfied + --> $DIR/associated-types-path-2.rs:35:14 + | +LL | f1(2u32, 4i32); + | ^^^^ the trait `Foo` is not implemented for `u32` + error[E0308]: mismatched types - --> $DIR/associated-types-path-2.rs:39:18 + --> $DIR/associated-types-path-2.rs:41:18 | LL | let _: i32 = f2(2i32); | --- ^^^^^^^^ expected `i32`, found `u32` @@ -50,7 +60,7 @@ help: you can convert a `u32` to an `i32` and panic if the converted value doesn LL | let _: i32 = f2(2i32).try_into().unwrap(); | ++++++++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index d509ff3598b50..baaab7fee679d 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:49:5 + --> $DIR/async-fn-nonsend.rs:49:17 | LL | assert_send(local_dropped_before_await()); - | ^^^^^^^^^^^ future returned by `local_dropped_before_await` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `local_dropped_before_await` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` note: future is not `Send` as this value is used across an await @@ -22,10 +22,10 @@ LL | fn assert_send(_: impl Send) {} | ^^^^ required by this bound in `assert_send` error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:51:5 + --> $DIR/async-fn-nonsend.rs:51:17 | LL | assert_send(non_send_temporary_in_match()); - | ^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` note: future is not `Send` as this value is used across an await @@ -45,10 +45,10 @@ LL | fn assert_send(_: impl Send) {} | ^^^^ required by this bound in `assert_send` error: future cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:53:5 + --> $DIR/async-fn-nonsend.rs:53:17 | LL | assert_send(non_sync_with_method_call()); - | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` | = help: the trait `Send` is not implemented for `dyn std::fmt::Write` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-64130-1-sync.stderr b/src/test/ui/async-await/issue-64130-1-sync.stderr index 69c7ff47456c0..12e4bfc3d48b6 100644 --- a/src/test/ui/async-await/issue-64130-1-sync.stderr +++ b/src/test/ui/async-await/issue-64130-1-sync.stderr @@ -1,8 +1,8 @@ error: future cannot be shared between threads safely - --> $DIR/issue-64130-1-sync.rs:21:5 + --> $DIR/issue-64130-1-sync.rs:21:13 | LL | is_sync(bar()); - | ^^^^^^^ future returned by `bar` is not `Sync` + | ^^^^^ future returned by `bar` is not `Sync` | = help: within `impl Future`, the trait `Sync` is not implemented for `Foo` note: future is not `Sync` as this value is used across an await diff --git a/src/test/ui/async-await/issue-64130-2-send.stderr b/src/test/ui/async-await/issue-64130-2-send.stderr index 933e9296848e9..9c94b8da8929a 100644 --- a/src/test/ui/async-await/issue-64130-2-send.stderr +++ b/src/test/ui/async-await/issue-64130-2-send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-64130-2-send.rs:21:5 + --> $DIR/issue-64130-2-send.rs:21:13 | LL | is_send(bar()); - | ^^^^^^^ future returned by `bar` is not `Send` + | ^^^^^ future returned by `bar` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Foo` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr index ec0fdd4a5551d..3dd1239e23dbe 100644 --- a/src/test/ui/async-await/issue-64130-3-other.stderr +++ b/src/test/ui/async-await/issue-64130-3-other.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future` - --> $DIR/issue-64130-3-other.rs:24:5 + --> $DIR/issue-64130-3-other.rs:24:12 | LL | async fn bar() { | - within this `impl Future` ... LL | is_qux(bar()); - | ^^^^^^ within `impl Future`, the trait `Qux` is not implemented for `Foo` + | ^^^^^ within `impl Future`, the trait `Qux` is not implemented for `Foo` | note: future does not implement `Qux` as this value is used across an await --> $DIR/issue-64130-3-other.rs:18:5 diff --git a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr index 472fffa61b791..7125c62dbaf9a 100644 --- a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr +++ b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-64130-non-send-future-diags.rs:21:5 + --> $DIR/issue-64130-non-send-future-diags.rs:21:13 | LL | is_send(foo()); - | ^^^^^^^ future returned by `foo` is not `Send` + | ^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issue-71137.stderr b/src/test/ui/async-await/issue-71137.stderr index 8903c09c17f0d..ac254346c08a6 100644 --- a/src/test/ui/async-await/issue-71137.stderr +++ b/src/test/ui/async-await/issue-71137.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> $DIR/issue-71137.rs:20:3 + --> $DIR/issue-71137.rs:20:14 | LL | fake_spawn(wrong_mutex()); - | ^^^^^^^^^^ future returned by `wrong_mutex` is not `Send` + | ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/async-await/issues/issue-67893.stderr b/src/test/ui/async-await/issues/issue-67893.stderr index 7321a38c02182..ee32a1a9e4fbb 100644 --- a/src/test/ui/async-await/issues/issue-67893.stderr +++ b/src/test/ui/async-await/issues/issue-67893.stderr @@ -1,8 +1,8 @@ error: generator cannot be sent between threads safely - --> $DIR/issue-67893.rs:9:5 + --> $DIR/issue-67893.rs:9:7 | LL | g(issue_67893::run()) - | ^ generator is not `Send` + | ^^^^^^^^^^^^^^^^^^ generator is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` note: required by a bound in `g` diff --git a/src/test/ui/async-await/pin-needed-to-poll-2.stderr b/src/test/ui/async-await/pin-needed-to-poll-2.stderr index 8c581ff2229fc..b63ea106d9026 100644 --- a/src/test/ui/async-await/pin-needed-to-poll-2.stderr +++ b/src/test/ui/async-await/pin-needed-to-poll-2.stderr @@ -1,8 +1,10 @@ error[E0277]: `PhantomPinned` cannot be unpinned - --> $DIR/pin-needed-to-poll-2.rs:43:9 + --> $DIR/pin-needed-to-poll-2.rs:43:18 | LL | Pin::new(&mut self.sleep).poll(cx) - | ^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned` + | -------- ^^^^^^^^^^^^^^^ within `Sleep`, the trait `Unpin` is not implemented for `PhantomPinned` + | | + | required by a bound introduced by this call | = note: consider using `Box::pin` note: required because it appears within the type `Sleep` diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr index e51db35925e4a..4202cbae7eb29 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `(): _Contains<&C>` is not satisfied - --> $DIR/issue-85848.rs:24:5 + --> $DIR/issue-85848.rs:24:29 | LL | writes_to_specific_path(&cap); - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `_Contains<&C>` is not implemented for `()` + | ----------------------- ^^^^ the trait `_Contains<&C>` is not implemented for `()` + | | + | required by a bound introduced by this call | note: required because of the requirements on the impl of `Contains<(), true>` for `&C` --> $DIR/issue-85848.rs:21:12 @@ -21,10 +23,12 @@ LL | fn writes_to_specific_path>(cap: &C) {} | ^^^^^^^^^^^^^ required by this bound in `writes_to_specific_path` error: unconstrained generic constant - --> $DIR/issue-85848.rs:24:5 + --> $DIR/issue-85848.rs:24:29 | LL | writes_to_specific_path(&cap); - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ----------------------- ^^^^ + | | + | required by a bound introduced by this call | = help: try adding a `where` bound using this expression: `where [(); { contains::() }]:` note: required because of the requirements on the impl of `Contains<(), true>` for `&C` diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.rs b/src/test/ui/hrtb/issue-62203-hrtb-ice.rs index 454d7e5e9cdea..80f099ce3c802 100644 --- a/src/test/ui/hrtb/issue-62203-hrtb-ice.rs +++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.rs @@ -37,8 +37,8 @@ trait Ty<'a> { fn main() { let v = Unit2.m( //~^ ERROR type mismatch - //~| ERROR type mismatch L { + //~^ ERROR type mismatch f : |x| { drop(x); Unit4 } }); } diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr index 97f53bc70e44e..4c5c59c22099a 100644 --- a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr +++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr @@ -10,10 +10,16 @@ LL | let v = Unit2.m( = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as FnOnce<((&'r u8,),)>>::Output == Unit3` - --> $DIR/issue-62203-hrtb-ice.rs:38:19 + --> $DIR/issue-62203-hrtb-ice.rs:40:9 | -LL | let v = Unit2.m( - | ^ expected struct `Unit4`, found struct `Unit3` +LL | let v = Unit2.m( + | - required by a bound introduced by this call +LL | +LL | / L { +LL | | +LL | | f : |x| { drop(x); Unit4 } +LL | | }); + | |_________^ expected struct `Unit4`, found struct `Unit3` | note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]>` --> $DIR/issue-62203-hrtb-ice.rs:17:16 diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr index 5a8e503601468..8c53b4105bb8b 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr @@ -1,11 +1,13 @@ error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:13:5 + --> $DIR/auto-trait-leak2.rs:13:10 | LL | fn before() -> impl Fn(i32) { | ------------ within this `impl Fn<(i32,)>` ... LL | send(before()); - | ^^^^ `Rc>` cannot be sent between threads safely + | ---- ^^^^^^^^ `Rc>` cannot be sent between threads safely + | | + | required by a bound introduced by this call | = help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]` @@ -17,10 +19,12 @@ LL | fn send(_: T) {} | ^^^^ required by this bound in `send` error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:16:5 + --> $DIR/auto-trait-leak2.rs:16:10 | LL | send(after()); - | ^^^^ `Rc>` cannot be sent between threads safely + | ---- ^^^^^^^ `Rc>` cannot be sent between threads safely + | | + | required by a bound introduced by this call ... LL | fn after() -> impl Fn(i32) { | ------------ within this `impl Fn<(i32,)>` diff --git a/src/test/ui/intrinsics/const-eval-select-bad.rs b/src/test/ui/intrinsics/const-eval-select-bad.rs index 8fbdc0c39c6aa..a3171187e69e5 100644 --- a/src/test/ui/intrinsics/const-eval-select-bad.rs +++ b/src/test/ui/intrinsics/const-eval-select-bad.rs @@ -7,6 +7,7 @@ const fn not_fn_items() { //~^ ERROR expected a `FnOnce<()>` closure const_eval_select((), 42, 0xDEADBEEF); //~^ ERROR expected a `FnOnce<()>` closure + //~| ERROR expected a `FnOnce<()>` closure } const fn foo(n: i32) -> i32 { diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr index 78647e92138c2..5e1ab584d80cf 100644 --- a/src/test/ui/intrinsics/const-eval-select-bad.stderr +++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr @@ -1,8 +1,8 @@ error[E0277]: expected a `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` - --> $DIR/const-eval-select-bad.rs:6:34 + --> $DIR/const-eval-select-bad.rs:6:27 | LL | const_eval_select((), || {}, || {}); - | ----------------- ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` + | ----------------- ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` | | | required by a bound introduced by this call | @@ -15,10 +15,10 @@ LL | F: ~const FnOnce, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select` error[E0277]: expected a `FnOnce<()>` closure, found `{integer}` - --> $DIR/const-eval-select-bad.rs:8:31 + --> $DIR/const-eval-select-bad.rs:8:27 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}` + | ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}` | | | required by a bound introduced by this call | @@ -30,8 +30,24 @@ note: required by a bound in `const_eval_select` LL | F: ~const FnOnce, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select` +error[E0277]: expected a `FnOnce<()>` closure, found `{integer}` + --> $DIR/const-eval-select-bad.rs:8:31 + | +LL | const_eval_select((), 42, 0xDEADBEEF); + | ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}` + | | + | required by a bound introduced by this call + | + = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | G: FnOnce + ~const Drop, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select` + error[E0271]: type mismatch resolving ` bool {bar} as FnOnce<(i32,)>>::Output == i32` - --> $DIR/const-eval-select-bad.rs:27:5 + --> $DIR/const-eval-select-bad.rs:28:5 | LL | const_eval_select((1,), foo, bar); | ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool` @@ -43,13 +59,13 @@ LL | G: FnOnce + ~const Drop, | ^^^^^^^^^^^^ required by this bound in `const_eval_select` error[E0631]: type mismatch in function arguments - --> $DIR/const-eval-select-bad.rs:32:37 + --> $DIR/const-eval-select-bad.rs:33:32 | LL | const fn foo(n: i32) -> i32 { | --------------------------- found signature of `fn(i32) -> _` ... LL | const_eval_select((true,), foo, baz); - | ----------------- ^^^ expected signature of `fn(bool) -> _` + | ----------------- ^^^ expected signature of `fn(bool) -> _` | | | required by a bound introduced by this call | @@ -59,7 +75,7 @@ note: required by a bound in `const_eval_select` LL | F: ~const FnOnce, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0271, E0277, E0631. For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/issues/issue-40827.stderr b/src/test/ui/issues/issue-40827.stderr index 3b2d232e61f7e..11c23e5b659b7 100644 --- a/src/test/ui/issues/issue-40827.stderr +++ b/src/test/ui/issues/issue-40827.stderr @@ -1,8 +1,10 @@ error[E0277]: `Rc` cannot be shared between threads safely - --> $DIR/issue-40827.rs:14:5 + --> $DIR/issue-40827.rs:14:7 | LL | f(Foo(Arc::new(Bar::B(None)))); - | ^ `Rc` cannot be shared between threads safely + | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `Bar`, the trait `Sync` is not implemented for `Rc` note: required because it appears within the type `Bar` @@ -23,10 +25,12 @@ LL | fn f(_: T) {} | ^^^^ required by this bound in `f` error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/issue-40827.rs:14:5 + --> $DIR/issue-40827.rs:14:7 | LL | f(Foo(Arc::new(Bar::B(None)))); - | ^ `Rc` cannot be sent between threads safely + | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc` cannot be sent between threads safely + | | + | required by a bound introduced by this call | = help: within `Bar`, the trait `Send` is not implemented for `Rc` note: required because it appears within the type `Bar` diff --git a/src/test/ui/mut/mutable-enum-indirect.stderr b/src/test/ui/mut/mutable-enum-indirect.stderr index 8ec478cd63fa1..9e1f4e1fe4ea9 100644 --- a/src/test/ui/mut/mutable-enum-indirect.stderr +++ b/src/test/ui/mut/mutable-enum-indirect.stderr @@ -1,8 +1,10 @@ error[E0277]: `NoSync` cannot be shared between threads safely - --> $DIR/mutable-enum-indirect.rs:17:5 + --> $DIR/mutable-enum-indirect.rs:17:9 | LL | bar(&x); - | ^^^ `NoSync` cannot be shared between threads safely + | --- ^^ `NoSync` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `&Foo`, the trait `Sync` is not implemented for `NoSync` note: required because it appears within the type `Foo` diff --git a/src/test/ui/no_send-enum.stderr b/src/test/ui/no_send-enum.stderr index 814f3473828e3..b5a14b551dc2d 100644 --- a/src/test/ui/no_send-enum.stderr +++ b/src/test/ui/no_send-enum.stderr @@ -1,8 +1,10 @@ error[E0277]: `NoSend` cannot be sent between threads safely - --> $DIR/no_send-enum.rs:16:5 + --> $DIR/no_send-enum.rs:16:9 | LL | bar(x); - | ^^^ `NoSend` cannot be sent between threads safely + | --- ^ `NoSend` cannot be sent between threads safely + | | + | required by a bound introduced by this call | = help: within `Foo`, the trait `Send` is not implemented for `NoSend` note: required because it appears within the type `Foo` diff --git a/src/test/ui/no_share-enum.stderr b/src/test/ui/no_share-enum.stderr index ad837863be9ed..5b453e0da3bbd 100644 --- a/src/test/ui/no_share-enum.stderr +++ b/src/test/ui/no_share-enum.stderr @@ -1,8 +1,10 @@ error[E0277]: `NoSync` cannot be shared between threads safely - --> $DIR/no_share-enum.rs:14:5 + --> $DIR/no_share-enum.rs:14:9 | LL | bar(x); - | ^^^ `NoSync` cannot be shared between threads safely + | --- ^ `NoSync` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `Foo`, the trait `Sync` is not implemented for `NoSync` note: required because it appears within the type `Foo` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 34cd1d2b1074d..efe46d7e81d3d 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -51,9 +51,6 @@ LL | struct ConstDropImplWithBounds(PhantomData); error[E0277]: the trait bound `NonTrivialDrop: A` is not satisfied --> $DIR/const-drop-fail.rs:49:5 | -LL | const _: () = check($exp); - | ----- required by a bound introduced by this call -... LL | ConstDropImplWithBounds::(PhantomData), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `NonTrivialDrop` | diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index 34cd1d2b1074d..efe46d7e81d3d 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -51,9 +51,6 @@ LL | struct ConstDropImplWithBounds(PhantomData); error[E0277]: the trait bound `NonTrivialDrop: A` is not satisfied --> $DIR/const-drop-fail.rs:49:5 | -LL | const _: () = check($exp); - | ----- required by a bound introduced by this call -... LL | ConstDropImplWithBounds::(PhantomData), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `A` is not implemented for `NonTrivialDrop` | diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr index 263d509075af8..0d9ecc32e08cd 100644 --- a/src/test/ui/suggestions/into-str.stderr +++ b/src/test/ui/suggestions/into-str.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `&str: From` is not satisfied - --> $DIR/into-str.rs:4:5 + --> $DIR/into-str.rs:4:9 | LL | foo(String::new()); - | ^^^ the trait `From` is not implemented for `&str` + | --- ^^^^^^^^^^^^^ the trait `From` is not implemented for `&str` + | | + | required by a bound introduced by this call | = note: to coerce a `String` into a `&str`, use `&*` as a prefix = note: required because of the requirements on the impl of `Into<&str>` for `String` diff --git a/src/test/ui/traits/issue-71136.stderr b/src/test/ui/traits/issue-71136.stderr index 23b78d023b600..d1e8affd065f9 100644 --- a/src/test/ui/traits/issue-71136.stderr +++ b/src/test/ui/traits/issue-71136.stderr @@ -5,7 +5,7 @@ LL | #[derive(Clone)] | ----- in this derive macro expansion LL | struct FooHolster { LL | the_foos: Vec, - | ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone` + | ^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Foo` | = note: required because of the requirements on the impl of `Clone` for `Vec` note: required by `clone` diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr index 8059a8ca71e43..1cf73fcdebd0b 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -49,7 +49,7 @@ LL | is_send((8, TestType)); | | | required by a bound introduced by this call | - = help: the trait `Send` is not implemented for `dummy1c::TestType` + = help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType` = note: required because it appears within the type `({integer}, dummy1c::TestType)` note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 @@ -86,7 +86,7 @@ LL | is_send(Box::new(Outer2(TestType))); | | | required by a bound introduced by this call | - = help: the trait `Send` is not implemented for `dummy3::TestType` + = help: within `Outer2`, the trait `Send` is not implemented for `dummy3::TestType` note: required because it appears within the type `Outer2` --> $DIR/negated-auto-traits-error.rs:12:8 | diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr index d60be4b1ccf9c..4a49d6e4ab8fd 100644 --- a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -1,11 +1,13 @@ error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leakage2.rs:17:5 + --> $DIR/auto-trait-leakage2.rs:17:13 | LL | type Foo = impl std::fmt::Debug; | -------------------- within this `impl Debug` ... LL | is_send(m::foo()); - | ^^^^^^^ `Rc` cannot be sent between threads safely + | ------- ^^^^^^^^ `Rc` cannot be sent between threads safely + | | + | required by a bound introduced by this call | = help: within `impl Debug`, the trait `Send` is not implemented for `Rc` = note: required because it appears within the type `impl Debug` diff --git a/src/test/ui/typeck/issue-90101.rs b/src/test/ui/typeck/issue-90101.rs new file mode 100644 index 0000000000000..1954ee6f1e7ce --- /dev/null +++ b/src/test/ui/typeck/issue-90101.rs @@ -0,0 +1,8 @@ +use std::path::{Path, PathBuf}; + +fn func(path: impl Into, code: impl Into) {} + +fn main() { + func(Path::new("hello").to_path_buf().to_string_lossy(), "world") + //~^ ERROR [E0277] +} diff --git a/src/test/ui/typeck/issue-90101.stderr b/src/test/ui/typeck/issue-90101.stderr new file mode 100644 index 0000000000000..998b636887f23 --- /dev/null +++ b/src/test/ui/typeck/issue-90101.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `PathBuf: From>` is not satisfied + --> $DIR/issue-90101.rs:6:10 + | +LL | func(Path::new("hello").to_path_buf().to_string_lossy(), "world") + | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `PathBuf` + | | + | required by a bound introduced by this call + | + = help: the following implementations were found: + > + >> + >> + > + > + = note: required because of the requirements on the impl of `Into` for `Cow<'_, str>` +note: required by a bound in `func` + --> $DIR/issue-90101.rs:3:20 + | +LL | fn func(path: impl Into, code: impl Into) {} + | ^^^^^^^^^^^^^ required by this bound in `func` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.stderr b/src/test/ui/typeck/typeck-unsafe-always-share.stderr index 4b5804253b23b..154e504996bc4 100644 --- a/src/test/ui/typeck/typeck-unsafe-always-share.stderr +++ b/src/test/ui/typeck/typeck-unsafe-always-share.stderr @@ -29,10 +29,12 @@ LL | fn test(s: T) {} | ^^^^ required by this bound in `test` error[E0277]: `UnsafeCell` cannot be shared between threads safely - --> $DIR/typeck-unsafe-always-share.rs:27:5 + --> $DIR/typeck-unsafe-always-share.rs:27:10 | LL | test(ms); - | ^^^^ `UnsafeCell` cannot be shared between threads safely + | ---- ^^ `UnsafeCell` cannot be shared between threads safely + | | + | required by a bound introduced by this call | = help: within `MySync`, the trait `Sync` is not implemented for `UnsafeCell` note: required because it appears within the type `MySync` diff --git a/src/test/ui/unsized-locals/unsized-exprs.stderr b/src/test/ui/unsized-locals/unsized-exprs.stderr index 6686e55130fb4..6960255d98797 100644 --- a/src/test/ui/unsized-locals/unsized-exprs.stderr +++ b/src/test/ui/unsized-locals/unsized-exprs.stderr @@ -16,7 +16,7 @@ LL | udrop::>(A { 0: *foo() }); | | | required by a bound introduced by this call | - = help: the trait `Sized` is not implemented for `[u8]` + = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `A<[u8]>` --> $DIR/unsized-exprs.rs:3:8 |