From f44ae98ceec2361a47e8822a8f5018d4443018ea Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jun 2022 09:18:25 -0700 Subject: [PATCH 1/4] Only label place where type is needed if span is meaningful --- .../src/infer/error_reporting/need_type_info.rs | 12 +++++++++--- .../src/traits/error_reporting/mod.rs | 14 ++++++++++++-- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 12 +++++++++--- compiler/rustc_typeck/src/check/writeback.rs | 2 ++ src/test/ui/array-slice-vec/infer_array_len.stderr | 1 - .../slice-pat-type-mismatches.stderr | 2 -- src/test/ui/cast/issue-85586.stderr | 2 -- .../ui/impl-trait/hidden-type-is-opaque-2.stderr | 4 ---- src/test/ui/issues/issue-15965.stderr | 2 -- src/test/ui/issues/issue-20261.stderr | 2 -- src/test/ui/issues/issue-2151.stderr | 3 ++- src/test/ui/issues/issue-51116.rs | 1 - src/test/ui/issues/issue-51116.stderr | 2 -- ...issue-88074-pat-range-type-inference-err.stderr | 2 -- src/test/ui/pattern/pat-tuple-bad-type.stderr | 4 +++- .../issue-42234-unknown-receiver-type.full.stderr | 4 ++-- ...-42234-unknown-receiver-type.generic_arg.stderr | 4 ++-- .../span/method-and-field-eager-resolution.stderr | 8 ++++++-- .../ui/span/type-annotations-needed-expr.stderr | 1 - .../closures_in_branches.stderr | 3 +-- src/test/ui/typeck/issue-65611.stderr | 2 -- .../unboxed-closures-failed-recursive-fn-2.stderr | 4 +++- 22 files changed, 51 insertions(+), 40 deletions(-) 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 d290752614c29..07dcf3876c806 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 @@ -313,11 +313,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn emit_inference_failure_err( &self, body_id: Option, - span: Span, + failure_span: Span, arg: GenericArg<'tcx>, // FIXME(#94483): Either use this or remove it. _impl_candidates: Vec>, error_code: TypeAnnotationNeeded, + should_label_span: bool, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let arg = self.resolve_vars_if_possible(arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); @@ -326,7 +327,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // If we don't have any typeck results we're outside // of a body, so we won't be able to get better info // here. - return self.bad_inference_failure_err(span, arg_data, error_code); + return self.bad_inference_failure_err(failure_span, arg_data, error_code); }; let typeck_results = typeck_results.borrow(); let typeck_results = &typeck_results; @@ -338,7 +339,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let Some(InferSource { span, kind }) = local_visitor.infer_source else { - return self.bad_inference_failure_err(span, arg_data, error_code) + return self.bad_inference_failure_err(failure_span, arg_data, error_code) }; let error_code = error_code.into(); @@ -347,6 +348,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &format!("type annotations needed{}", kind.ty_msg(self)), error_code, ); + + if should_label_span && !failure_span.overlaps(span) { + err.span_label(failure_span, "type must be known at this point"); + } + match kind { InferSourceKind::LetBinding { insert_span, pattern_name, ty } => { let suggestion_msg = if let Some(name) = pattern_name { 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 debb9e8295122..b525643330690 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2002,6 +2002,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { subst, vec![], ErrorCode::E0282, + false, ) .emit(); } @@ -2019,6 +2020,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { subst, impl_candidates, ErrorCode::E0283, + false, ); let obligation = Obligation::new( @@ -2110,7 +2112,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { return; } - self.emit_inference_failure_err(body_id, span, arg, vec![], ErrorCode::E0282) + self.emit_inference_failure_err(body_id, span, arg, vec![], ErrorCode::E0282, false) } ty::PredicateKind::Subtype(data) => { @@ -2124,7 +2126,14 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { let SubtypePredicate { a_is_expected: _, a, b } = data; // both must be type variables, or the other would've been instantiated assert!(a.is_ty_var() && b.is_ty_var()); - self.emit_inference_failure_err(body_id, span, a.into(), vec![], ErrorCode::E0282) + self.emit_inference_failure_err( + body_id, + span, + a.into(), + vec![], + ErrorCode::E0282, + false, + ) } ty::PredicateKind::Projection(data) => { let self_ty = data.projection_ty.self_ty(); @@ -2140,6 +2149,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { self_ty.into(), vec![], ErrorCode::E0284, + false, ); err.note(&format!("cannot satisfy `{}`", predicate)); err diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 5ad5692e7623c..bce2e85de845d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1538,9 +1538,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } else { if !self.is_tainted_by_errors() { - self.emit_inference_failure_err((**self).body_id, sp, ty.into(), vec![], E0282) - .note("type must be known at this point") - .emit(); + self.emit_inference_failure_err( + (**self).body_id, + sp, + ty.into(), + vec![], + E0282, + true, + ) + .emit(); } let err = self.tcx.ty_error(); self.demand_suptype(sp, err, ty); diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 9459cf5f8ca80..67160b98b9dc0 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -694,6 +694,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { t.into(), vec![], E0282, + false, ) .emit(); } @@ -708,6 +709,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { c.into(), vec![], E0282, + false, ) .emit(); } diff --git a/src/test/ui/array-slice-vec/infer_array_len.stderr b/src/test/ui/array-slice-vec/infer_array_len.stderr index 8da6d97251ba1..919550cac3087 100644 --- a/src/test/ui/array-slice-vec/infer_array_len.stderr +++ b/src/test/ui/array-slice-vec/infer_array_len.stderr @@ -4,7 +4,6 @@ error[E0282]: type annotations needed LL | let [_, _] = a.into(); | ^^^^^^ | - = note: type must be known at this point help: consider giving this pattern a type | LL | let [_, _]: _ = a.into(); diff --git a/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr index 20a5b99845bbc..70a4cbebeee98 100644 --- a/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr +++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr @@ -27,8 +27,6 @@ error[E0282]: type annotations needed | LL | [] => {} | ^^ cannot infer type - | - = note: type must be known at this point error: aborting due to 5 previous errors diff --git a/src/test/ui/cast/issue-85586.stderr b/src/test/ui/cast/issue-85586.stderr index 271885a133a95..ed8a6fc62e9dd 100644 --- a/src/test/ui/cast/issue-85586.stderr +++ b/src/test/ui/cast/issue-85586.stderr @@ -3,8 +3,6 @@ error[E0282]: type annotations needed | LL | let b = (a + 1) as usize; | ^^^^^^^ cannot infer type - | - = note: type must be known at this point error: aborting due to previous error diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr b/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr index 11ba5aa7867fe..957052feba95b 100644 --- a/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr +++ b/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr @@ -3,16 +3,12 @@ error[E0282]: type annotations needed | LL | cont.reify_as(); | ^^^^ cannot infer type - | - = note: type must be known at this point error[E0282]: type annotations needed --> $DIR/hidden-type-is-opaque-2.rs:18:9 | LL | cont.reify_as(); | ^^^^ cannot infer type - | - = note: type must be known at this point error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-15965.stderr b/src/test/ui/issues/issue-15965.stderr index 90377c19dee02..fe06810b8dff4 100644 --- a/src/test/ui/issues/issue-15965.stderr +++ b/src/test/ui/issues/issue-15965.stderr @@ -5,8 +5,6 @@ LL | / { return () } LL | | LL | | () | |______^ cannot infer type - | - = note: type must be known at this point error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20261.stderr b/src/test/ui/issues/issue-20261.stderr index 73468c7ca1687..9ac751e4dc437 100644 --- a/src/test/ui/issues/issue-20261.stderr +++ b/src/test/ui/issues/issue-20261.stderr @@ -3,8 +3,6 @@ error[E0282]: type annotations needed | LL | i.clone(); | ^^^^^ cannot infer type - | - = note: type must be known at this point error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2151.stderr b/src/test/ui/issues/issue-2151.stderr index e0d946205ad0a..31a8ca5fbfac8 100644 --- a/src/test/ui/issues/issue-2151.stderr +++ b/src/test/ui/issues/issue-2151.stderr @@ -3,8 +3,9 @@ error[E0282]: type annotations needed | LL | let x = panic!(); | ^ +LL | x.clone(); + | - type must be known at this point | - = note: type must be known at this point help: consider giving `x` an explicit type | LL | let x: _ = panic!(); diff --git a/src/test/ui/issues/issue-51116.rs b/src/test/ui/issues/issue-51116.rs index c979c7b2cdd76..4c21cbfc61d43 100644 --- a/src/test/ui/issues/issue-51116.rs +++ b/src/test/ui/issues/issue-51116.rs @@ -5,7 +5,6 @@ fn main() { *tile = 0; //~^ ERROR type annotations needed //~| NOTE cannot infer type - //~| NOTE type must be known at this point } } diff --git a/src/test/ui/issues/issue-51116.stderr b/src/test/ui/issues/issue-51116.stderr index 399b421ab163e..c07f8735eb2c7 100644 --- a/src/test/ui/issues/issue-51116.stderr +++ b/src/test/ui/issues/issue-51116.stderr @@ -3,8 +3,6 @@ error[E0282]: type annotations needed | LL | *tile = 0; | ^^^^^ cannot infer type - | - = note: type must be known at this point error: aborting due to previous error diff --git a/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr b/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr index 06a279925edbc..8e528f8c1db94 100644 --- a/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr +++ b/src/test/ui/pattern/issue-88074-pat-range-type-inference-err.stderr @@ -12,8 +12,6 @@ error[E0282]: type annotations needed | LL | Zero::ZERO ..= Zero::ZERO => {}, | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | - = note: type must be known at this point error: aborting due to 2 previous errors diff --git a/src/test/ui/pattern/pat-tuple-bad-type.stderr b/src/test/ui/pattern/pat-tuple-bad-type.stderr index 11b28987848d6..3342b8e4002b9 100644 --- a/src/test/ui/pattern/pat-tuple-bad-type.stderr +++ b/src/test/ui/pattern/pat-tuple-bad-type.stderr @@ -3,8 +3,10 @@ error[E0282]: type annotations needed | LL | let x; | ^ +... +LL | (..) => {} + | ---- type must be known at this point | - = note: type must be known at this point help: consider giving `x` an explicit type | LL | let x: _; diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr index cd3ffdc6f9d60..2b17899085020 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr @@ -3,8 +3,9 @@ error[E0282]: type annotations needed | LL | let x: Option<_> = None; | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` +LL | x.unwrap().method_that_could_exist_on_some_type(); + | ---------- type must be known at this point | - = note: type must be known at this point help: consider specifying the generic argument | LL | let x: Option<_> = None::; @@ -16,7 +17,6 @@ error[E0282]: type annotations needed LL | .sum::<_>() | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` | - = note: type must be known at this point help: consider specifying the generic argument | LL | .sum::<_>() diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr index b6a3f07f5715f..d93d54e878bc8 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr @@ -3,8 +3,9 @@ error[E0282]: type annotations needed | LL | let x: Option<_> = None; | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` +LL | x.unwrap().method_that_could_exist_on_some_type(); + | ---------- type must be known at this point | - = note: type must be known at this point help: consider specifying the generic argument | LL | let x: Option<_> = None::; @@ -16,7 +17,6 @@ error[E0282]: type annotations needed LL | .sum::<_>() | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` | - = note: type must be known at this point help: consider specifying the generic argument | LL | .sum::() diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr index 2dd650f38ce39..7d240589a3f13 100644 --- a/src/test/ui/span/method-and-field-eager-resolution.stderr +++ b/src/test/ui/span/method-and-field-eager-resolution.stderr @@ -3,8 +3,10 @@ error[E0282]: type annotations needed | LL | let mut x = Default::default(); | ^^^^^ +LL | +LL | x.0; + | - type must be known at this point | - = note: type must be known at this point help: consider giving `x` an explicit type | LL | let mut x: _ = Default::default(); @@ -15,8 +17,10 @@ error[E0282]: type annotations needed | LL | let mut x = Default::default(); | ^^^^^ +LL | +LL | x[0]; + | - type must be known at this point | - = note: type must be known at this point help: consider giving `x` an explicit type | LL | let mut x: _ = Default::default(); diff --git a/src/test/ui/span/type-annotations-needed-expr.stderr b/src/test/ui/span/type-annotations-needed-expr.stderr index e4a8f7464626c..9dff6c64db46f 100644 --- a/src/test/ui/span/type-annotations-needed-expr.stderr +++ b/src/test/ui/span/type-annotations-needed-expr.stderr @@ -4,7 +4,6 @@ error[E0282]: type annotations needed LL | let _ = (vec![1,2,3]).into_iter().sum() as f64; | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` | - = note: type must be known at this point help: consider specifying the generic argument | LL | let _ = (vec![1,2,3]).into_iter().sum::() as f64; diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr index b7a7871143c63..08f7d8c9f2db6 100644 --- a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr +++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -14,9 +14,8 @@ error[E0282]: type annotations needed --> $DIR/closures_in_branches.rs:21:10 | LL | |x| x.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |x: _| x.len() diff --git a/src/test/ui/typeck/issue-65611.stderr b/src/test/ui/typeck/issue-65611.stderr index 5f831291a3851..003c630790d2c 100644 --- a/src/test/ui/typeck/issue-65611.stderr +++ b/src/test/ui/typeck/issue-65611.stderr @@ -3,8 +3,6 @@ error[E0282]: type annotations needed | LL | let x = buffer.last().unwrap().0.clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` - | - = note: type must be known at this point error[E0609]: no field `0` on type `&_` --> $DIR/issue-65611.rs:59:36 diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 666ab79b65c32..ff2a597bed065 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -3,8 +3,10 @@ error[E0282]: type annotations needed for `Option` | LL | let mut closure0 = None; | ^^^^^^^^^^^^ +... +LL | return c(); + | --- type must be known at this point | - = note: type must be known at this point help: consider giving `closure0` an explicit type, where the placeholders `_` are specified | LL | let mut closure0: Option = None; From ca0105ba4e3c846f3d3e25705a401db949c8dd40 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jun 2022 09:28:27 -0700 Subject: [PATCH 2/4] Show source of ambiguity in a few more places --- .../src/traits/error_reporting/mod.rs | 6 +++--- .../generic_arg_infer/issue-91614.stderr | 2 +- .../inference/cannot-infer-partial-try-return.stderr | 3 +++ .../ui/inference/erase-type-params-in-label.stderr | 4 ++-- src/test/ui/inference/issue-72616.stderr | 4 +++- src/test/ui/inference/issue-72690.stderr | 2 +- src/test/ui/inference/issue-86162-1.stderr | 4 +++- src/test/ui/inference/issue-86162-2.stderr | 4 +++- src/test/ui/issues/issue-69455.stderr | 4 +++- src/test/ui/issues/issue-7813.stderr | 2 +- .../suggestions/suggest-closure-return-type-1.stderr | 2 +- .../suggestions/suggest-closure-return-type-2.stderr | 2 +- .../suggestions/suggest-closure-return-type-3.stderr | 2 +- src/test/ui/traits/issue-77982.stderr | 12 ++++++++---- .../type-check/cannot_infer_local_or_array.stderr | 2 +- 15 files changed, 35 insertions(+), 20 deletions(-) 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 b525643330690..00b4d0857ac2c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2020,7 +2020,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { subst, impl_candidates, ErrorCode::E0283, - false, + true, ); let obligation = Obligation::new( @@ -2132,7 +2132,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { a.into(), vec![], ErrorCode::E0282, - false, + true, ) } ty::PredicateKind::Projection(data) => { @@ -2149,7 +2149,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { self_ty.into(), vec![], ErrorCode::E0284, - false, + true, ); err.note(&format!("cannot satisfy `{}`", predicate)); err diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr index 463605e2431d6..688db695fa848 100644 --- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -2,7 +2,7 @@ error[E0283]: type annotations needed for `Mask<_, LANES>` --> $DIR/issue-91614.rs:6:9 | LL | let y = Mask::<_, _>::splat(false); - | ^ + | ^ ------------------- type must be known at this point | = note: cannot satisfy `_: MaskElement` note: required by a bound in `Mask::::splat` diff --git a/src/test/ui/inference/cannot-infer-partial-try-return.stderr b/src/test/ui/inference/cannot-infer-partial-try-return.stderr index 220602c124cb1..c1e43f0b721f5 100644 --- a/src/test/ui/inference/cannot-infer-partial-try-return.stderr +++ b/src/test/ui/inference/cannot-infer-partial-try-return.stderr @@ -3,6 +3,9 @@ error[E0282]: type annotations needed for `Result<(), QualifiedError<_>>` | LL | let x = || -> Result<_, QualifiedError<_>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | infallible()?; + | ------------- type must be known at this point | help: try giving this closure an explicit return type | diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr index fd58844c2380a..7bb281802d2ce 100644 --- a/src/test/ui/inference/erase-type-params-in-label.stderr +++ b/src/test/ui/inference/erase-type-params-in-label.stderr @@ -2,7 +2,7 @@ error[E0283]: type annotations needed for `Foo` --> $DIR/erase-type-params-in-label.rs:2:9 | LL | let foo = foo(1, ""); - | ^^^ + | ^^^ --- type must be known at this point | = note: cannot satisfy `_: Default` note: required by a bound in `foo` @@ -23,7 +23,7 @@ error[E0283]: type annotations needed for `Bar` --> $DIR/erase-type-params-in-label.rs:5:9 | LL | let bar = bar(1, ""); - | ^^^ + | ^^^ --- type must be known at this point | = note: cannot satisfy `_: Default` note: required by a bound in `bar` diff --git a/src/test/ui/inference/issue-72616.stderr b/src/test/ui/inference/issue-72616.stderr index 3c53d8126e778..a71ce9a8ef27a 100644 --- a/src/test/ui/inference/issue-72616.stderr +++ b/src/test/ui/inference/issue-72616.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-72616.rs:20:37 | LL | if String::from("a") == "a".try_into().unwrap() {} - | ^^^^^^^^ + | -- ^^^^^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `String: PartialEq<_>` found in the `alloc` crate: - impl PartialEq for String; diff --git a/src/test/ui/inference/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr index 9edf14ef291f9..d4eeda07366a8 100644 --- a/src/test/ui/inference/issue-72690.stderr +++ b/src/test/ui/inference/issue-72690.stderr @@ -55,7 +55,7 @@ error[E0283]: type annotations needed for `&T` --> $DIR/issue-72690.rs:17:9 | LL | let _ = "x".as_ref(); - | ^ + | ^ ------ type must be known at this point | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; diff --git a/src/test/ui/inference/issue-86162-1.stderr b/src/test/ui/inference/issue-86162-1.stderr index 6641b29b30b0b..e395e65fad066 100644 --- a/src/test/ui/inference/issue-86162-1.stderr +++ b/src/test/ui/inference/issue-86162-1.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-86162-1.rs:7:9 | LL | foo(gen()); //<- Do not suggest `foo::()`! - | ^^^ cannot infer type of the type parameter `T` declared on the function `gen` + | --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` + | | + | type must be known at this point | = note: cannot satisfy `_: Clone` note: required by a bound in `foo` diff --git a/src/test/ui/inference/issue-86162-2.stderr b/src/test/ui/inference/issue-86162-2.stderr index d2a026a9269c6..30e6e10eaa2fd 100644 --- a/src/test/ui/inference/issue-86162-2.stderr +++ b/src/test/ui/inference/issue-86162-2.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-86162-2.rs:12:14 | LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::()`! - | ^^^ cannot infer type of the type parameter `T` declared on the function `gen` + | -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` + | | + | type must be known at this point | = note: cannot satisfy `_: Clone` note: required by a bound in `Foo::bar` diff --git a/src/test/ui/issues/issue-69455.stderr b/src/test/ui/issues/issue-69455.stderr index 6c4eafbc8b3a1..9be6c2f8564ff 100644 --- a/src/test/ui/issues/issue-69455.stderr +++ b/src/test/ui/issues/issue-69455.stderr @@ -14,7 +14,9 @@ error[E0283]: type annotations needed --> $DIR/issue-69455.rs:29:41 | LL | println!("{}", 23u64.test(xs.iter().sum())); - | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | | + | type must be known at this point | note: multiple `impl`s satisfying `u64: Test<_>` found --> $DIR/issue-69455.rs:11:1 diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 3aee61bd5a54c..2a747f679a84d 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `&[_; 0]` --> $DIR/issue-7813.rs:2:9 | LL | let v = &[]; - | ^ + | ^ --- type must be known at this point | help: consider giving `v` an explicit type, where the placeholders `_` are specified | diff --git a/src/test/ui/suggestions/suggest-closure-return-type-1.stderr b/src/test/ui/suggestions/suggest-closure-return-type-1.stderr index 3116211b52c90..f4c2eb7ff34ae 100644 --- a/src/test/ui/suggestions/suggest-closure-return-type-1.stderr +++ b/src/test/ui/suggestions/suggest-closure-return-type-1.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `[_; 0]` --> $DIR/suggest-closure-return-type-1.rs:4:18 | LL | unbound_drop(|| -> _ { [] }); - | ^^^^^^^ + | ^^^^^^^ -- type must be known at this point | help: try giving this closure an explicit return type | diff --git a/src/test/ui/suggestions/suggest-closure-return-type-2.stderr b/src/test/ui/suggestions/suggest-closure-return-type-2.stderr index f368e7de467ca..88bf263043d2c 100644 --- a/src/test/ui/suggestions/suggest-closure-return-type-2.stderr +++ b/src/test/ui/suggestions/suggest-closure-return-type-2.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `[_; 0]` --> $DIR/suggest-closure-return-type-2.rs:4:18 | LL | unbound_drop(|| { [] }) - | ^^ + | ^^ -- type must be known at this point | help: try giving this closure an explicit return type | diff --git a/src/test/ui/suggestions/suggest-closure-return-type-3.stderr b/src/test/ui/suggestions/suggest-closure-return-type-3.stderr index 4176932153353..bc4107528d274 100644 --- a/src/test/ui/suggestions/suggest-closure-return-type-3.stderr +++ b/src/test/ui/suggestions/suggest-closure-return-type-3.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `[_; 0]` --> $DIR/suggest-closure-return-type-3.rs:4:18 | LL | unbound_drop(|| []); - | ^^ + | ^^ -- type must be known at this point | help: try giving this closure an explicit return type | diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 5aa42b5b1d3ed..a2d23c4e9dfad 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -26,7 +26,9 @@ error[E0283]: type annotations needed --> $DIR/issue-77982.rs:8:10 | LL | opts.get(opt.as_ref()); - | ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get` + | ^^^ ------ type must be known at this point + | | + | cannot infer type of the type parameter `Q` declared on the associated function `get` | = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: - impl AsRef for String; @@ -42,7 +44,9 @@ error[E0283]: type annotations needed --> $DIR/issue-77982.rs:13:59 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); - | ^^^^ + | --------- ^^^^ + | | + | type must be known at this point | = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`: - impl From for u32; @@ -59,7 +63,7 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:36:9 | LL | let _ = ().foo(); - | ^ + | ^ --- type must be known at this point | note: multiple `impl`s satisfying `(): Foo<'_, _>` found --> $DIR/issue-77982.rs:29:1 @@ -77,7 +81,7 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:40:9 | LL | let _ = (&()).bar(); - | ^ + | ^ --- type must be known at this point | note: multiple `impl`s satisfying `&(): Bar<'_, _>` found --> $DIR/issue-77982.rs:32:1 diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index d68d5e5d40b9e..e823bad2668ae 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `[_; 0]` --> $DIR/cannot_infer_local_or_array.rs:2:9 | LL | let x = []; - | ^ + | ^ -- type must be known at this point | help: consider giving `x` an explicit type, where the placeholders `_` are specified | From 12ab6bfafddac39c401fe418b9fa5dbda5ce7ceb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jun 2022 10:42:23 -0700 Subject: [PATCH 3/4] Don't point at Self type if we can't find an infer variable in ambiguous trait predicate --- compiler/rustc_middle/src/ty/mod.rs | 8 +++ .../src/traits/error_reporting/mod.rs | 63 +++++++++++-------- .../coherence-overlap-trait-alias.stderr | 4 +- .../issue-72787.min.stderr | 8 +-- .../generic_const_exprs/issue-72787.rs | 4 +- src/test/ui/issues/issue-12028.stderr | 10 ++- src/test/ui/issues/issue-21974.stderr | 4 +- src/test/ui/issues/issue-24424.stderr | 4 +- src/test/ui/issues/issue-69683.stderr | 10 ++- src/test/ui/issues/issue-71584.stderr | 14 ++++- src/test/ui/lifetimes/issue-34979.stderr | 4 +- .../marker_trait_attr/region-overlap.stderr | 8 +-- src/test/ui/traits/issue-85735.rs | 2 +- src/test/ui/traits/issue-85735.stderr | 4 +- .../ui/type/type-check/issue-40294.stderr | 4 +- 15 files changed, 94 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 00403ff044c40..f73eca5bf612c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -914,9 +914,17 @@ impl<'tcx> Term<'tcx> { pub fn ty(&self) -> Option> { if let Term::Ty(ty) = self { Some(*ty) } else { None } } + pub fn ct(&self) -> Option> { if let Term::Const(c) = self { Some(*c) } else { None } } + + pub fn into_arg(self) -> GenericArg<'tcx> { + match self { + Term::Ty(ty) => ty.into(), + Term::Const(c) => c.into(), + } + } } /// This kind of predicate has no *direct* correspondent in the 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 00b4d0857ac2c..3201ea1e27150 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1970,13 +1970,31 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Pick the first substitution that still contains inference variables as the one // we're going to emit an error for. If there are none (see above), fall back to - // the substitution for `Self`. - let subst = { - let substs = data.trait_ref.substs; - substs - .iter() - .find(|s| s.has_infer_types_or_consts()) - .unwrap_or_else(|| substs[0]) + // a more general error. + let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts()); + + let mut err = if let Some(subst) = subst { + let impl_candidates = self + .find_similar_impl_candidates(trait_ref) + .into_iter() + .map(|candidate| candidate.trait_ref) + .collect(); + self.emit_inference_failure_err( + body_id, + span, + subst, + impl_candidates, + ErrorCode::E0283, + true, + ) + } else { + struct_span_err!( + self.tcx.sess, + span, + E0283, + "type annotations needed: cannot satisfy `{}`", + predicate, + ) }; // This is kind of a hack: it frequently happens that some earlier @@ -1999,30 +2017,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { self.emit_inference_failure_err( body_id, span, - subst, + trait_ref.self_ty().skip_binder().into(), vec![], ErrorCode::E0282, false, ) .emit(); } + err.cancel(); return; } - let impl_candidates = self - .find_similar_impl_candidates(trait_ref) - .into_iter() - .map(|candidate| candidate.trait_ref) - .collect(); - let mut err = self.emit_inference_failure_err( - body_id, - span, - subst, - impl_candidates, - ErrorCode::E0283, - true, - ); - let obligation = Obligation::new( obligation.cause.clone(), obligation.param_env, @@ -2136,17 +2141,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ) } ty::PredicateKind::Projection(data) => { - let self_ty = data.projection_ty.self_ty(); - let term = data.term; if predicate.references_error() || self.is_tainted_by_errors() { return; } - if self_ty.needs_infer() && term.needs_infer() { - // We do this for the `foo.collect()?` case to produce a suggestion. + let subst = data + .projection_ty + .substs + .iter() + .chain(Some(data.term.into_arg())) + .find(|g| g.has_infer_types_or_consts()); + if let Some(subst) = subst { let mut err = self.emit_inference_failure_err( body_id, span, - self_ty.into(), + subst, vec![], ErrorCode::E0284, true, @@ -2154,6 +2162,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { err.note(&format!("cannot satisfy `{}`", predicate)); err } else { + // If we can't find a substitution, just print a generic error let mut err = struct_span_err!( self.tcx.sess, span, diff --git a/src/test/ui/coherence/coherence-overlap-trait-alias.stderr b/src/test/ui/coherence/coherence-overlap-trait-alias.stderr index 421c86ee51a52..e324c1e799f9e 100644 --- a/src/test/ui/coherence/coherence-overlap-trait-alias.stderr +++ b/src/test/ui/coherence/coherence-overlap-trait-alias.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `u32: C` --> $DIR/coherence-overlap-trait-alias.rs:15:6 | LL | impl C for u32 {} - | ^ cannot infer type for type `u32` + | ^ | note: multiple `impl`s satisfying `u32: C` found --> $DIR/coherence-overlap-trait-alias.rs:14:1 diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index 02dce4f7a97e8..41afaec86b6e4 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -34,19 +34,19 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: const parameters may only be used as standalone arguments, i.e. `J` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, - | ^^^^ cannot infer type for struct `IsLessOrEqual` + | ^^^^ | = note: cannot satisfy `IsLessOrEqual: True` -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, - | ^^^^ cannot infer type for struct `IsLessOrEqual` + | ^^^^ | = note: cannot satisfy `IsLessOrEqual: True` diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs b/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs index 77ad57f0640fa..c651bf1c8de9d 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.rs @@ -19,8 +19,8 @@ struct S; impl S where IsLessOrEqual: True, -//[min]~^ Error type annotations needed [E0283] -//[min]~| Error type annotations needed [E0283] +//[min]~^ Error type annotations needed +//[min]~| Error type annotations needed IsLessOrEqual: True, IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, //[min]~^ Error generic parameters may not be used in const operations diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr index 30cb7a1df8071..8d6b81c24b682 100644 --- a/src/test/ui/issues/issue-12028.stderr +++ b/src/test/ui/issues/issue-12028.stderr @@ -1,8 +1,14 @@ -error[E0284]: type annotations needed: cannot satisfy `<_ as StreamHasher>::S == ::S` +error[E0284]: type annotations needed --> $DIR/issue-12028.rs:27:14 | LL | self.input_stream(&mut stream); - | ^^^^^^^^^^^^ cannot satisfy `<_ as StreamHasher>::S == ::S` + | ^^^^^^^^^^^^ + | + = note: cannot satisfy `<_ as StreamHasher>::S == ::S` +help: try using a fully qualified path to specify the expected types + | +LL | >::input_stream(self, &mut stream); + | ++++++++++++++++++++++++++++++++++++ ~ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr index dfabde9abc978..4e010a13653e7 100644 --- a/src/test/ui/issues/issue-21974.stderr +++ b/src/test/ui/issues/issue-21974.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo` --> $DIR/issue-21974.rs:11:19 | LL | where &'a T : Foo, - | ^^^ cannot infer type for reference `&'a T` + | ^^^ | = note: cannot satisfy `&'a T: Foo` diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr index fa59da852f901..8f3b2ac73199c 100644 --- a/src/test/ui/issues/issue-24424.stderr +++ b/src/test/ui/issues/issue-24424.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `T0: Trait0<'l0>` --> $DIR/issue-24424.rs:4:57 | LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} - | ^^^^^^^^^^^ cannot infer type for type parameter `T0` + | ^^^^^^^^^^^ | = note: cannot satisfy `T0: Trait0<'l0>` diff --git a/src/test/ui/issues/issue-69683.stderr b/src/test/ui/issues/issue-69683.stderr index 9c71ecffa2682..193de1a35cf1a 100644 --- a/src/test/ui/issues/issue-69683.stderr +++ b/src/test/ui/issues/issue-69683.stderr @@ -1,8 +1,14 @@ -error[E0284]: type annotations needed: cannot satisfy `>::Array == [u8; 3]` +error[E0284]: type annotations needed --> $DIR/issue-69683.rs:30:10 | LL | 0u16.foo(b); - | ^^^ cannot satisfy `>::Array == [u8; 3]` + | ^^^ + | + = note: cannot satisfy `>::Array == [u8; 3]` +help: try using a fully qualified path to specify the expected types + | +LL | >::foo(0u16, b); + | +++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-69683.rs:30:10 diff --git a/src/test/ui/issues/issue-71584.stderr b/src/test/ui/issues/issue-71584.stderr index 1c216e6498295..6ddb7657301cd 100644 --- a/src/test/ui/issues/issue-71584.stderr +++ b/src/test/ui/issues/issue-71584.stderr @@ -1,8 +1,16 @@ -error[E0284]: type annotations needed: cannot satisfy `>::Output == u64` - --> $DIR/issue-71584.rs:4:11 +error[E0284]: type annotations needed + --> $DIR/issue-71584.rs:4:15 | LL | d = d % n.into(); - | ^ cannot satisfy `>::Output == u64` + | - ^^^^ + | | + | type must be known at this point + | + = note: cannot satisfy `>::Output == u64` +help: try using a fully qualified path to specify the expected types + | +LL | d = d % >::into(n); + | +++++++++++++++++++++++ ~ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/issue-34979.stderr b/src/test/ui/lifetimes/issue-34979.stderr index 1b97f8d818a45..5832c4d173c10 100644 --- a/src/test/ui/lifetimes/issue-34979.stderr +++ b/src/test/ui/lifetimes/issue-34979.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `&'a (): Foo` --> $DIR/issue-34979.rs:6:13 | LL | &'a (): Foo, - | ^^^ cannot infer type for reference `&'a ()` + | ^^^ | = note: cannot satisfy `&'a (): Foo` diff --git a/src/test/ui/marker_trait_attr/region-overlap.stderr b/src/test/ui/marker_trait_attr/region-overlap.stderr index 2eeab801e3d9c..6631fe987e275 100644 --- a/src/test/ui/marker_trait_attr/region-overlap.stderr +++ b/src/test/ui/marker_trait_attr/region-overlap.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `(&'static (), &'a ()): A` --> $DIR/region-overlap.rs:5:10 | LL | impl<'a> A for (&'static (), &'a ()) {} - | ^ cannot infer type for tuple `(&'static (), &'a ())` + | ^ | note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found --> $DIR/region-overlap.rs:5:1 @@ -12,11 +12,11 @@ LL | impl<'a> A for (&'static (), &'a ()) {} LL | impl<'a> A for (&'a (), &'static ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `(&'a (), &'static ()): A` --> $DIR/region-overlap.rs:6:10 | LL | impl<'a> A for (&'a (), &'static ()) {} - | ^ cannot infer type for tuple `(&'a (), &'static ())` + | ^ | note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found --> $DIR/region-overlap.rs:5:1 diff --git a/src/test/ui/traits/issue-85735.rs b/src/test/ui/traits/issue-85735.rs index 16e874ee21e62..fb387a9c90965 100644 --- a/src/test/ui/traits/issue-85735.rs +++ b/src/test/ui/traits/issue-85735.rs @@ -5,7 +5,7 @@ trait Foo {} impl<'a, 'b, T> Foo for T where T: FnMut(&'a ()), - //~^ ERROR: type annotations needed [E0283] + //~^ ERROR: type annotations needed T: FnMut(&'b ()), { } diff --git a/src/test/ui/traits/issue-85735.stderr b/src/test/ui/traits/issue-85735.stderr index 33b12ef09ec26..fa280135beb2d 100644 --- a/src/test/ui/traits/issue-85735.stderr +++ b/src/test/ui/traits/issue-85735.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `T: FnMut<(&'a (),)>` --> $DIR/issue-85735.rs:7:8 | LL | T: FnMut(&'a ()), - | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^^^^^^ | = note: cannot satisfy `T: FnMut<(&'a (),)>` diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr index 6d1e490bcf330..75feb5698eb63 100644 --- a/src/test/ui/type/type-check/issue-40294.stderr +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -1,8 +1,8 @@ -error[E0283]: type annotations needed +error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo` --> $DIR/issue-40294.rs:6:19 | LL | where &'a T : Foo, - | ^^^ cannot infer type for reference `&'a T` + | ^^^ | = note: cannot satisfy `&'a T: Foo` From 6711313f76b712271b10080067ebd4e0034b6be8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 1 Jul 2022 01:30:48 +0000 Subject: [PATCH 4/4] Move Sized check before first error is created --- .../src/traits/error_reporting/mod.rs | 62 +++++++++---------- .../branches3.stderr | 12 ++-- .../closures_in_branches.stderr | 3 +- .../ui/type-alias-impl-trait/fallback.stderr | 2 + 4 files changed, 38 insertions(+), 41 deletions(-) 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 3201ea1e27150..fa56219b409d1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1958,6 +1958,37 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { if predicate.references_error() { return; } + + // This is kind of a hack: it frequently happens that some earlier + // error prevents types from being fully inferred, and then we get + // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we + // could just skip over all checks where the self-ty is an + // inference variable, but I was afraid that there might be an + // inference variable created, registered as an obligation, and + // then never forced by writeback, and hence by skipping here we'd + // be ignoring the fact that we don't KNOW the type works + // out. Though even that would probably be harmless, given that + // we're only talking about builtin traits, which are known to be + // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // avoid inundating the user with unnecessary errors, but we now + // check upstream for type errors and don't add the obligations to + // begin with in those cases. + if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { + if !self.is_tainted_by_errors() { + self.emit_inference_failure_err( + body_id, + span, + trait_ref.self_ty().skip_binder().into(), + vec![], + ErrorCode::E0282, + false, + ) + .emit(); + } + return; + } + // Typically, this ambiguity should only happen if // there are unresolved type inference variables // (otherwise it would suggest a coherence @@ -1997,37 +2028,6 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ) }; - // This is kind of a hack: it frequently happens that some earlier - // error prevents types from being fully inferred, and then we get - // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we - // could just skip over all checks where the self-ty is an - // inference variable, but I was afraid that there might be an - // inference variable created, registered as an obligation, and - // then never forced by writeback, and hence by skipping here we'd - // be ignoring the fact that we don't KNOW the type works - // out. Though even that would probably be harmless, given that - // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to - // avoid inundating the user with unnecessary errors, but we now - // check upstream for type errors and don't add the obligations to - // begin with in those cases. - if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - if !self.is_tainted_by_errors() { - self.emit_inference_failure_err( - body_id, - span, - trait_ref.self_ty().skip_binder().into(), - vec![], - ErrorCode::E0282, - false, - ) - .emit(); - } - err.cancel(); - return; - } - let obligation = Obligation::new( obligation.cause.clone(), obligation.param_env, diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr index 77ce1d48480ad..420104e526d9b 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr @@ -2,9 +2,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:8:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() @@ -14,9 +13,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:15:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() @@ -26,9 +24,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:23:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() @@ -38,9 +35,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:30:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr index 08f7d8c9f2db6..48b7946ea820e 100644 --- a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr +++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -2,9 +2,8 @@ error[E0282]: type annotations needed --> $DIR/closures_in_branches.rs:7:10 | LL | |x| x.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |x: _| x.len() diff --git a/src/test/ui/type-alias-impl-trait/fallback.stderr b/src/test/ui/type-alias-impl-trait/fallback.stderr index e009399a60abf..e767bfdb08b6b 100644 --- a/src/test/ui/type-alias-impl-trait/fallback.stderr +++ b/src/test/ui/type-alias-impl-trait/fallback.stderr @@ -1,6 +1,8 @@ error[E0283]: type annotations needed --> $DIR/fallback.rs:24:5 | +LL | fn unconstrained_foo() -> Wrapper { + | ------------ type must be known at this point LL | Wrapper::Second | ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper` |