diff options
| author | Michael Goulet <michael@errs.io> | 2022-06-25 10:42:23 -0700 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-07-01 17:38:34 +0000 |
| commit | 12ab6bfafddac39c401fe418b9fa5dbda5ce7ceb (patch) | |
| tree | 2924b6c726857542e87942db0360b434076ca7b0 /compiler/rustc_trait_selection/src | |
| parent | ca0105ba4e3c846f3d3e25705a401db949c8dd40 (diff) | |
| download | rust-12ab6bfafddac39c401fe418b9fa5dbda5ce7ceb.tar.gz rust-12ab6bfafddac39c401fe418b9fa5dbda5ce7ceb.zip | |
Don't point at Self type if we can't find an infer variable in ambiguous trait predicate
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs | 63 |
1 files changed, 36 insertions, 27 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 00b4d0857ac..3201ea1e271 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, |
