diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index f8ee006b9c89..c44e53af5b3c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -532,6 +532,22 @@ enum InferSourceKind<'tcx> { }, } +impl<'tcx> InferSource<'tcx> { + /// Returns the span where we're going to insert our suggestion. + /// + /// Used when computing the cost of this infer source to check whether + /// we're inside of a macro expansion. + fn main_insert_span(&self) -> Span { + match self.kind { + InferSourceKind::LetBinding { insert_span, .. } => insert_span, + InferSourceKind::ClosureArg { insert_span, .. } => insert_span, + InferSourceKind::GenericArg { insert_span, .. } => insert_span, + InferSourceKind::FullyQualifiedMethodCall { receiver, .. } => receiver.span, + InferSourceKind::ClosureReturn { data, .. } => data.span(), + } + } +} + impl<'tcx> InferSourceKind<'tcx> { fn ty_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> String { match *self { @@ -638,7 +654,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { // The sources are listed in order of preference here. let tcx = self.infcx.tcx; let ctx = CostCtxt { tcx }; - match source.kind { + let base_cost = match source.kind { InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty), InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty), InferSourceKind::GenericArg { def_id, generic_args, .. } => { @@ -655,7 +671,12 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => { 30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 } } - } + }; + + let suggestion_may_apply = + if source.main_insert_span().can_be_used_for_suggestions() { 0 } else { 10000 }; + + base_cost + suggestion_may_apply } /// Uses `fn source_cost` to determine whether this inference source is preferable to diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 00f8a747c712..be60cda68b9f 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -1,15 +1,13 @@ -error[E0282]: type annotations needed - --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 +error[E0282]: type annotations needed for `(Vec,)` + --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9 | LL | let (x, ) = (vec![], ); - | ^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec` + | ^^^^^ | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider specifying the generic argument - --> $SRC_DIR/alloc/src/macros.rs:LL:COL +help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | $crate::__rust_force_expr!($crate::vec::Vec::::new()) - | +++++ +LL | let (x, ): (Vec,) = (vec![], ); + | +++++++++++ error: aborting due to previous error