]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trait_selection/traits/error_reporting/mod.rs
Fix whitespace in `?Sized` structured suggestion
[rust.git] / src / librustc_trait_selection / traits / error_reporting / mod.rs
index 19ed6b50f92a624ba00d7082927edbce4b6d17ac..0d53df3bf4b466ecba0500bc69560e8a7e498df8 100644 (file)
@@ -283,6 +283,8 @@ fn report_selection_error(
                             .unwrap_or(false);
                         let is_from = format!("{}", trait_ref.print_only_trait_path())
                             .starts_with("std::convert::From<");
+                        let is_unsize =
+                            { Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait() };
                         let (message, note) = if is_try && is_from {
                             (
                                 Some(format!(
@@ -400,11 +402,23 @@ fn report_selection_error(
                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
                         self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
                         self.note_version_mismatch(&mut err, &trait_ref);
+                        self.suggest_await_before_try(&mut err, &obligation, &trait_ref, span);
                         if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) {
                             err.emit();
                             return;
                         }
 
+                        if is_unsize {
+                            // If the obligation failed due to a missing implementation of the
+                            // `Unsize` trait, give a pointer to why that might be the case
+                            err.note(
+                                "all implementations of `Unsize` are provided \
+                                automatically by the compiler, see \
+                                <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> \
+                                for more information",
+                            );
+                        }
+
                         // Try to report a help message
                         if !trait_ref.has_infer_types_or_consts()
                             && self.predicate_can_apply(obligation.param_env, trait_ref)
@@ -427,12 +441,16 @@ fn report_selection_error(
                                 let impl_candidates = self.find_similar_impl_candidates(trait_ref);
                                 self.report_similar_impl_candidates(impl_candidates, &mut err);
                             }
-                            self.suggest_change_mut(
-                                &obligation,
-                                &mut err,
-                                &trait_ref,
-                                points_at_arg,
-                            );
+                            // Changing mutability doesn't make a difference to whether we have
+                            // an `Unsize` impl (Fixes ICE in #71036)
+                            if !is_unsize {
+                                self.suggest_change_mut(
+                                    &obligation,
+                                    &mut err,
+                                    &trait_ref,
+                                    points_at_arg,
+                                );
+                            }
                         }
 
                         // If this error is due to `!: Trait` not implemented but `(): Trait` is
@@ -570,12 +588,21 @@ fn report_selection_error(
                     }
 
                     ty::Predicate::WellFormed(ty) => {
-                        // WF predicates cannot themselves make
-                        // errors. They can only block due to
-                        // ambiguity; otherwise, they always
-                        // degenerate into other obligations
-                        // (which may fail).
-                        span_bug!(span, "WF predicate not satisfied for {:?}", ty);
+                        if !self.tcx.sess.opts.debugging_opts.chalk {
+                            // WF predicates cannot themselves make
+                            // errors. They can only block due to
+                            // ambiguity; otherwise, they always
+                            // degenerate into other obligations
+                            // (which may fail).
+                            span_bug!(span, "WF predicate not satisfied for {:?}", ty);
+                        } else {
+                            // FIXME: we'll need a better message which takes into account
+                            // which bounds actually failed to hold.
+                            self.tcx.sess.struct_span_err(
+                                span,
+                                &format!("the type `{}` is not well-formed (chalk)", ty),
+                            )
+                        }
                     }
 
                     ty::Predicate::ConstEvaluatable(..) => {
@@ -1185,7 +1212,6 @@ fn type_category(t: Ty<'_>) -> Option<u32> {
                 ty::Foreign(..) => Some(19),
                 ty::GeneratorWitness(..) => Some(20),
                 ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None,
-                ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
             }
         }
 
@@ -1491,12 +1517,26 @@ fn maybe_report_ambiguity(
             ty::Predicate::Projection(ref data) => {
                 let trait_ref = data.to_poly_trait_ref(self.tcx);
                 let self_ty = trait_ref.self_ty();
+                let ty = data.skip_binder().ty;
                 if predicate.references_error() {
                     return;
                 }
-                let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
-                err.note(&format!("cannot satisfy `{}`", predicate));
-                err
+                if self_ty.needs_infer() && ty.needs_infer() {
+                    // We do this for the `foo.collect()?` case to produce a suggestion.
+                    let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
+                    err.note(&format!("cannot satisfy `{}`", predicate));
+                    err
+                } else {
+                    let mut err = struct_span_err!(
+                        self.tcx.sess,
+                        span,
+                        E0284,
+                        "type annotations needed: cannot satisfy `{}`",
+                        predicate,
+                    );
+                    err.span_label(span, &format!("cannot satisfy `{}`", predicate));
+                    err
+                }
             }
 
             _ => {
@@ -1615,7 +1655,7 @@ fn suggest_unsized_bound_if_applicable(
                     {
                         let (span, separator) = match param.bounds {
                             [] => (span.shrink_to_hi(), ":"),
-                            [.., bound] => (bound.span().shrink_to_hi(), " + "),
+                            [.., bound] => (bound.span().shrink_to_hi(), " +"),
                         };
                         err.span_suggestion_verbose(
                             span,