]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/error_reporting/mod.rs
f15fa779534e0c9dd8b316eefeed85b20549d109
[rust.git] / src / librustc / traits / error_reporting / mod.rs
1 pub mod on_unimplemented;
2 pub mod suggestions;
3
4 use super::{
5     ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode,
6     MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause,
7     ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote,
8     OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError,
9     TraitNotObjectSafe,
10 };
11
12 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
13 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
14 use crate::infer::{self, InferCtxt};
15 use crate::mir::interpret::ErrorHandled;
16 use crate::session::DiagnosticMessageId;
17 use crate::traits::object_safety_violations;
18 use crate::ty::error::ExpectedFound;
19 use crate::ty::fast_reject;
20 use crate::ty::fold::TypeFolder;
21 use crate::ty::SubtypePredicate;
22 use crate::ty::{
23     self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
24 };
25
26 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
27 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
28 use rustc_hir as hir;
29 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
30 use rustc_span::source_map::SourceMap;
31 use rustc_span::{ExpnKind, Span, DUMMY_SP};
32 use std::fmt;
33 use syntax::ast;
34
35 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
36     pub fn report_fulfillment_errors(
37         &self,
38         errors: &[FulfillmentError<'tcx>],
39         body_id: Option<hir::BodyId>,
40         fallback_has_occurred: bool,
41     ) {
42         #[derive(Debug)]
43         struct ErrorDescriptor<'tcx> {
44             predicate: ty::Predicate<'tcx>,
45             index: Option<usize>, // None if this is an old error
46         }
47
48         let mut error_map: FxHashMap<_, Vec<_>> = self
49             .reported_trait_errors
50             .borrow()
51             .iter()
52             .map(|(&span, predicates)| {
53                 (
54                     span,
55                     predicates
56                         .iter()
57                         .map(|&predicate| ErrorDescriptor { predicate, index: None })
58                         .collect(),
59                 )
60             })
61             .collect();
62
63         for (index, error) in errors.iter().enumerate() {
64             // We want to ignore desugarings here: spans are equivalent even
65             // if one is the result of a desugaring and the other is not.
66             let mut span = error.obligation.cause.span;
67             let expn_data = span.ctxt().outer_expn_data();
68             if let ExpnKind::Desugaring(_) = expn_data.kind {
69                 span = expn_data.call_site;
70             }
71
72             error_map.entry(span).or_default().push(ErrorDescriptor {
73                 predicate: error.obligation.predicate,
74                 index: Some(index),
75             });
76
77             self.reported_trait_errors
78                 .borrow_mut()
79                 .entry(span)
80                 .or_default()
81                 .push(error.obligation.predicate.clone());
82         }
83
84         // We do this in 2 passes because we want to display errors in order, though
85         // maybe it *is* better to sort errors by span or something.
86         let mut is_suppressed = vec![false; errors.len()];
87         for (_, error_set) in error_map.iter() {
88             // We want to suppress "duplicate" errors with the same span.
89             for error in error_set {
90                 if let Some(index) = error.index {
91                     // Suppress errors that are either:
92                     // 1) strictly implied by another error.
93                     // 2) implied by an error with a smaller index.
94                     for error2 in error_set {
95                         if error2.index.map_or(false, |index2| is_suppressed[index2]) {
96                             // Avoid errors being suppressed by already-suppressed
97                             // errors, to prevent all errors from being suppressed
98                             // at once.
99                             continue;
100                         }
101
102                         if self.error_implies(&error2.predicate, &error.predicate)
103                             && !(error2.index >= error.index
104                                 && self.error_implies(&error.predicate, &error2.predicate))
105                         {
106                             info!("skipping {:?} (implied by {:?})", error, error2);
107                             is_suppressed[index] = true;
108                             break;
109                         }
110                     }
111                 }
112             }
113         }
114
115         for (error, suppressed) in errors.iter().zip(is_suppressed) {
116             if !suppressed {
117                 self.report_fulfillment_error(error, body_id, fallback_has_occurred);
118             }
119         }
120     }
121
122     // returns if `cond` not occurring implies that `error` does not occur - i.e., that
123     // `error` occurring implies that `cond` occurs.
124     fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool {
125         if cond == error {
126             return true;
127         }
128
129         let (cond, error) = match (cond, error) {
130             (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error, _)) => (cond, error),
131             _ => {
132                 // FIXME: make this work in other cases too.
133                 return false;
134             }
135         };
136
137         for implication in super::elaborate_predicates(self.tcx, vec![*cond]) {
138             if let ty::Predicate::Trait(implication, _) = implication {
139                 let error = error.to_poly_trait_ref();
140                 let implication = implication.to_poly_trait_ref();
141                 // FIXME: I'm just not taking associated types at all here.
142                 // Eventually I'll need to implement param-env-aware
143                 // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
144                 let param_env = ty::ParamEnv::empty();
145                 if self.can_sub(param_env, error, implication).is_ok() {
146                     debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
147                     return true;
148                 }
149             }
150         }
151
152         false
153     }
154
155     fn report_fulfillment_error(
156         &self,
157         error: &FulfillmentError<'tcx>,
158         body_id: Option<hir::BodyId>,
159         fallback_has_occurred: bool,
160     ) {
161         debug!("report_fulfillment_error({:?})", error);
162         match error.code {
163             FulfillmentErrorCode::CodeSelectionError(ref selection_error) => {
164                 self.report_selection_error(
165                     &error.obligation,
166                     selection_error,
167                     fallback_has_occurred,
168                     error.points_at_arg_span,
169                 );
170             }
171             FulfillmentErrorCode::CodeProjectionError(ref e) => {
172                 self.report_projection_error(&error.obligation, e);
173             }
174             FulfillmentErrorCode::CodeAmbiguity => {
175                 self.maybe_report_ambiguity(&error.obligation, body_id);
176             }
177             FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
178                 self.report_mismatched_types(
179                     &error.obligation.cause,
180                     expected_found.expected,
181                     expected_found.found,
182                     err.clone(),
183                 )
184                 .emit();
185             }
186         }
187     }
188
189     fn report_projection_error(
190         &self,
191         obligation: &PredicateObligation<'tcx>,
192         error: &MismatchedProjectionTypes<'tcx>,
193     ) {
194         let predicate = self.resolve_vars_if_possible(&obligation.predicate);
195
196         if predicate.references_error() {
197             return;
198         }
199
200         self.probe(|_| {
201             let err_buf;
202             let mut err = &error.err;
203             let mut values = None;
204
205             // try to find the mismatched types to report the error with.
206             //
207             // this can fail if the problem was higher-ranked, in which
208             // cause I have no idea for a good error message.
209             if let ty::Predicate::Projection(ref data) = predicate {
210                 let mut selcx = SelectionContext::new(self);
211                 let (data, _) = self.replace_bound_vars_with_fresh_vars(
212                     obligation.cause.span,
213                     infer::LateBoundRegionConversionTime::HigherRankedType,
214                     data,
215                 );
216                 let mut obligations = vec![];
217                 let normalized_ty = super::normalize_projection_type(
218                     &mut selcx,
219                     obligation.param_env,
220                     data.projection_ty,
221                     obligation.cause.clone(),
222                     0,
223                     &mut obligations,
224                 );
225
226                 debug!(
227                     "report_projection_error obligation.cause={:?} obligation.param_env={:?}",
228                     obligation.cause, obligation.param_env
229                 );
230
231                 debug!(
232                     "report_projection_error normalized_ty={:?} data.ty={:?}",
233                     normalized_ty, data.ty
234                 );
235
236                 let is_normalized_ty_expected = match &obligation.cause.code {
237                     ObligationCauseCode::ItemObligation(_)
238                     | ObligationCauseCode::BindingObligation(_, _)
239                     | ObligationCauseCode::ObjectCastObligation(_) => false,
240                     _ => true,
241                 };
242
243                 if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
244                     is_normalized_ty_expected,
245                     normalized_ty,
246                     data.ty,
247                 ) {
248                     values = Some(infer::ValuePairs::Types(ExpectedFound::new(
249                         is_normalized_ty_expected,
250                         normalized_ty,
251                         data.ty,
252                     )));
253
254                     err_buf = error;
255                     err = &err_buf;
256                 }
257             }
258
259             let msg = format!("type mismatch resolving `{}`", predicate);
260             let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg);
261             let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
262             if fresh {
263                 let mut diag = struct_span_err!(
264                     self.tcx.sess,
265                     obligation.cause.span,
266                     E0271,
267                     "type mismatch resolving `{}`",
268                     predicate
269                 );
270                 self.note_type_err(&mut diag, &obligation.cause, None, values, err);
271                 self.note_obligation_cause(&mut diag, obligation);
272                 diag.emit();
273             }
274         });
275     }
276
277     fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
278         /// returns the fuzzy category of a given type, or None
279         /// if the type can be equated to any type.
280         fn type_category(t: Ty<'_>) -> Option<u32> {
281             match t.kind {
282                 ty::Bool => Some(0),
283                 ty::Char => Some(1),
284                 ty::Str => Some(2),
285                 ty::Int(..) | ty::Uint(..) | ty::Infer(ty::IntVar(..)) => Some(3),
286                 ty::Float(..) | ty::Infer(ty::FloatVar(..)) => Some(4),
287                 ty::Ref(..) | ty::RawPtr(..) => Some(5),
288                 ty::Array(..) | ty::Slice(..) => Some(6),
289                 ty::FnDef(..) | ty::FnPtr(..) => Some(7),
290                 ty::Dynamic(..) => Some(8),
291                 ty::Closure(..) => Some(9),
292                 ty::Tuple(..) => Some(10),
293                 ty::Projection(..) => Some(11),
294                 ty::Param(..) => Some(12),
295                 ty::Opaque(..) => Some(13),
296                 ty::Never => Some(14),
297                 ty::Adt(adt, ..) => match adt.adt_kind() {
298                     AdtKind::Struct => Some(15),
299                     AdtKind::Union => Some(16),
300                     AdtKind::Enum => Some(17),
301                 },
302                 ty::Generator(..) => Some(18),
303                 ty::Foreign(..) => Some(19),
304                 ty::GeneratorWitness(..) => Some(20),
305                 ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None,
306                 ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
307             }
308         }
309
310         match (type_category(a), type_category(b)) {
311             (Some(cat_a), Some(cat_b)) => match (&a.kind, &b.kind) {
312                 (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b,
313                 _ => cat_a == cat_b,
314             },
315             // infer and error can be equated to all types
316             _ => true,
317         }
318     }
319
320     fn describe_generator(&self, body_id: hir::BodyId) -> Option<&'static str> {
321         self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| match gen_kind {
322             hir::GeneratorKind::Gen => "a generator",
323             hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block",
324             hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function",
325             hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure",
326         })
327     }
328
329     fn find_similar_impl_candidates(
330         &self,
331         trait_ref: ty::PolyTraitRef<'tcx>,
332     ) -> Vec<ty::TraitRef<'tcx>> {
333         let simp = fast_reject::simplify_type(self.tcx, trait_ref.skip_binder().self_ty(), true);
334         let all_impls = self.tcx.all_impls(trait_ref.def_id());
335
336         match simp {
337             Some(simp) => all_impls
338                 .iter()
339                 .filter_map(|&def_id| {
340                     let imp = self.tcx.impl_trait_ref(def_id).unwrap();
341                     let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true);
342                     if let Some(imp_simp) = imp_simp {
343                         if simp != imp_simp {
344                             return None;
345                         }
346                     }
347
348                     Some(imp)
349                 })
350                 .collect(),
351             None => {
352                 all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect()
353             }
354         }
355     }
356
357     fn report_similar_impl_candidates(
358         &self,
359         impl_candidates: Vec<ty::TraitRef<'tcx>>,
360         err: &mut DiagnosticBuilder<'_>,
361     ) {
362         if impl_candidates.is_empty() {
363             return;
364         }
365
366         let len = impl_candidates.len();
367         let end = if impl_candidates.len() <= 5 { impl_candidates.len() } else { 4 };
368
369         let normalize = |candidate| {
370             self.tcx.infer_ctxt().enter(|ref infcx| {
371                 let normalized = infcx
372                     .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
373                     .normalize(candidate)
374                     .ok();
375                 match normalized {
376                     Some(normalized) => format!("\n  {:?}", normalized.value),
377                     None => format!("\n  {:?}", candidate),
378                 }
379             })
380         };
381
382         // Sort impl candidates so that ordering is consistent for UI tests.
383         let mut normalized_impl_candidates =
384             impl_candidates.iter().map(normalize).collect::<Vec<String>>();
385
386         // Sort before taking the `..end` range,
387         // because the ordering of `impl_candidates` may not be deterministic:
388         // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507
389         normalized_impl_candidates.sort();
390
391         err.help(&format!(
392             "the following implementations were found:{}{}",
393             normalized_impl_candidates[..end].join(""),
394             if len > 5 { format!("\nand {} others", len - 4) } else { String::new() }
395         ));
396     }
397
398     /// Reports that an overflow has occurred and halts compilation. We
399     /// halt compilation unconditionally because it is important that
400     /// overflows never be masked -- they basically represent computations
401     /// whose result could not be truly determined and thus we can't say
402     /// if the program type checks or not -- and they are unusual
403     /// occurrences in any case.
404     pub fn report_overflow_error<T>(
405         &self,
406         obligation: &Obligation<'tcx, T>,
407         suggest_increasing_limit: bool,
408     ) -> !
409     where
410         T: fmt::Display + TypeFoldable<'tcx>,
411     {
412         let predicate = self.resolve_vars_if_possible(&obligation.predicate);
413         let mut err = struct_span_err!(
414             self.tcx.sess,
415             obligation.cause.span,
416             E0275,
417             "overflow evaluating the requirement `{}`",
418             predicate
419         );
420
421         if suggest_increasing_limit {
422             self.suggest_new_overflow_limit(&mut err);
423         }
424
425         self.note_obligation_cause_code(
426             &mut err,
427             &obligation.predicate,
428             &obligation.cause.code,
429             &mut vec![],
430         );
431
432         err.emit();
433         self.tcx.sess.abort_if_errors();
434         bug!();
435     }
436
437     /// Reports that a cycle was detected which led to overflow and halts
438     /// compilation. This is equivalent to `report_overflow_error` except
439     /// that we can give a more helpful error message (and, in particular,
440     /// we do not suggest increasing the overflow limit, which is not
441     /// going to help).
442     pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
443         let cycle = self.resolve_vars_if_possible(&cycle.to_owned());
444         assert!(cycle.len() > 0);
445
446         debug!("report_overflow_error_cycle: cycle={:?}", cycle);
447
448         self.report_overflow_error(&cycle[0], false);
449     }
450
451     pub fn report_extra_impl_obligation(
452         &self,
453         error_span: Span,
454         item_name: ast::Name,
455         _impl_item_def_id: DefId,
456         trait_item_def_id: DefId,
457         requirement: &dyn fmt::Display,
458     ) -> DiagnosticBuilder<'tcx> {
459         let msg = "impl has stricter requirements than trait";
460         let sp = self.tcx.sess.source_map().def_span(error_span);
461
462         let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg);
463
464         if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) {
465             let span = self.tcx.sess.source_map().def_span(trait_item_span);
466             err.span_label(span, format!("definition of `{}` from trait", item_name));
467         }
468
469         err.span_label(sp, format!("impl has extra requirement {}", requirement));
470
471         err
472     }
473
474     /// Gets the parent trait chain start
475     fn get_parent_trait_ref(
476         &self,
477         code: &ObligationCauseCode<'tcx>,
478     ) -> Option<(String, Option<Span>)> {
479         match code {
480             &ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
481                 let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
482                 match self.get_parent_trait_ref(&data.parent_code) {
483                     Some(t) => Some(t),
484                     None => {
485                         let ty = parent_trait_ref.skip_binder().self_ty();
486                         let span =
487                             TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id));
488                         Some((ty.to_string(), span))
489                     }
490                 }
491             }
492             _ => None,
493         }
494     }
495
496     pub fn report_selection_error(
497         &self,
498         obligation: &PredicateObligation<'tcx>,
499         error: &SelectionError<'tcx>,
500         fallback_has_occurred: bool,
501         points_at_arg: bool,
502     ) {
503         let tcx = self.tcx;
504         let span = obligation.cause.span;
505
506         let mut err = match *error {
507             SelectionError::Unimplemented => {
508                 if let ObligationCauseCode::CompareImplMethodObligation {
509                     item_name,
510                     impl_item_def_id,
511                     trait_item_def_id,
512                 }
513                 | ObligationCauseCode::CompareImplTypeObligation {
514                     item_name,
515                     impl_item_def_id,
516                     trait_item_def_id,
517                 } = obligation.cause.code
518                 {
519                     self.report_extra_impl_obligation(
520                         span,
521                         item_name,
522                         impl_item_def_id,
523                         trait_item_def_id,
524                         &format!("`{}`", obligation.predicate),
525                     )
526                     .emit();
527                     return;
528                 }
529                 match obligation.predicate {
530                     ty::Predicate::Trait(ref trait_predicate, _) => {
531                         let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
532
533                         if self.tcx.sess.has_errors() && trait_predicate.references_error() {
534                             return;
535                         }
536                         let trait_ref = trait_predicate.to_poly_trait_ref();
537                         let (post_message, pre_message, type_def) = self
538                             .get_parent_trait_ref(&obligation.cause.code)
539                             .map(|(t, s)| {
540                                 (
541                                     format!(" in `{}`", t),
542                                     format!("within `{}`, ", t),
543                                     s.map(|s| (format!("within this `{}`", t), s)),
544                                 )
545                             })
546                             .unwrap_or_default();
547
548                         let OnUnimplementedNote { message, label, note, enclosing_scope } =
549                             self.on_unimplemented_note(trait_ref, obligation);
550                         let have_alt_message = message.is_some() || label.is_some();
551                         let is_try = self
552                             .tcx
553                             .sess
554                             .source_map()
555                             .span_to_snippet(span)
556                             .map(|s| &s == "?")
557                             .unwrap_or(false);
558                         let is_from = format!("{}", trait_ref.print_only_trait_path())
559                             .starts_with("std::convert::From<");
560                         let (message, note) = if is_try && is_from {
561                             (
562                                 Some(format!(
563                                     "`?` couldn't convert the error to `{}`",
564                                     trait_ref.self_ty(),
565                                 )),
566                                 Some(
567                                     "the question mark operation (`?`) implicitly performs a \
568                                      conversion on the error value using the `From` trait"
569                                         .to_owned(),
570                                 ),
571                             )
572                         } else {
573                             (message, note)
574                         };
575
576                         let mut err = struct_span_err!(
577                             self.tcx.sess,
578                             span,
579                             E0277,
580                             "{}",
581                             message.unwrap_or_else(|| format!(
582                                 "the trait bound `{}` is not satisfied{}",
583                                 trait_ref.without_const().to_predicate(),
584                                 post_message,
585                             ))
586                         );
587
588                         let explanation =
589                             if obligation.cause.code == ObligationCauseCode::MainFunctionType {
590                                 "consider using `()`, or a `Result`".to_owned()
591                             } else {
592                                 format!(
593                                     "{}the trait `{}` is not implemented for `{}`",
594                                     pre_message,
595                                     trait_ref.print_only_trait_path(),
596                                     trait_ref.self_ty(),
597                                 )
598                             };
599
600                         if self.suggest_add_reference_to_arg(
601                             &obligation,
602                             &mut err,
603                             &trait_ref,
604                             points_at_arg,
605                             have_alt_message,
606                         ) {
607                             self.note_obligation_cause(&mut err, obligation);
608                             err.emit();
609                             return;
610                         }
611                         if let Some(ref s) = label {
612                             // If it has a custom `#[rustc_on_unimplemented]`
613                             // error message, let's display it as the label!
614                             err.span_label(span, s.as_str());
615                             err.help(&explanation);
616                         } else {
617                             err.span_label(span, explanation);
618                         }
619                         if let Some((msg, span)) = type_def {
620                             err.span_label(span, &msg);
621                         }
622                         if let Some(ref s) = note {
623                             // If it has a custom `#[rustc_on_unimplemented]` note, let's display it
624                             err.note(s.as_str());
625                         }
626                         if let Some(ref s) = enclosing_scope {
627                             let enclosing_scope_span = tcx.def_span(
628                                 tcx.hir()
629                                     .opt_local_def_id(obligation.cause.body_id)
630                                     .unwrap_or_else(|| {
631                                         tcx.hir().body_owner_def_id(hir::BodyId {
632                                             hir_id: obligation.cause.body_id,
633                                         })
634                                     }),
635                             );
636
637                             err.span_label(enclosing_scope_span, s.as_str());
638                         }
639
640                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
641                         self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg);
642                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
643                         self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
644                         self.note_version_mismatch(&mut err, &trait_ref);
645                         if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) {
646                             err.emit();
647                             return;
648                         }
649
650                         // Try to report a help message
651                         if !trait_ref.has_infer_types()
652                             && self.predicate_can_apply(obligation.param_env, trait_ref)
653                         {
654                             // If a where-clause may be useful, remind the
655                             // user that they can add it.
656                             //
657                             // don't display an on-unimplemented note, as
658                             // these notes will often be of the form
659                             //     "the type `T` can't be frobnicated"
660                             // which is somewhat confusing.
661                             self.suggest_restricting_param_bound(
662                                 &mut err,
663                                 &trait_ref,
664                                 obligation.cause.body_id,
665                             );
666                         } else {
667                             if !have_alt_message {
668                                 // Can't show anything else useful, try to find similar impls.
669                                 let impl_candidates = self.find_similar_impl_candidates(trait_ref);
670                                 self.report_similar_impl_candidates(impl_candidates, &mut err);
671                             }
672                             self.suggest_change_mut(
673                                 &obligation,
674                                 &mut err,
675                                 &trait_ref,
676                                 points_at_arg,
677                             );
678                         }
679
680                         // If this error is due to `!: Trait` not implemented but `(): Trait` is
681                         // implemented, and fallback has occurred, then it could be due to a
682                         // variable that used to fallback to `()` now falling back to `!`. Issue a
683                         // note informing about the change in behaviour.
684                         if trait_predicate.skip_binder().self_ty().is_never()
685                             && fallback_has_occurred
686                         {
687                             let predicate = trait_predicate.map_bound(|mut trait_pred| {
688                                 trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
689                                     self.tcx.mk_unit(),
690                                     &trait_pred.trait_ref.substs[1..],
691                                 );
692                                 trait_pred
693                             });
694                             let unit_obligation = Obligation {
695                                 predicate: ty::Predicate::Trait(
696                                     predicate,
697                                     ast::Constness::NotConst,
698                                 ),
699                                 ..obligation.clone()
700                             };
701                             if self.predicate_may_hold(&unit_obligation) {
702                                 err.note(
703                                     "the trait is implemented for `()`. \
704                                          Possibly this error has been caused by changes to \
705                                          Rust's type-inference algorithm \
706                                          (see: https://github.com/rust-lang/rust/issues/48950 \
707                                          for more info). Consider whether you meant to use the \
708                                          type `()` here instead.",
709                                 );
710                             }
711                         }
712
713                         err
714                     }
715
716                     ty::Predicate::Subtype(ref predicate) => {
717                         // Errors for Subtype predicates show up as
718                         // `FulfillmentErrorCode::CodeSubtypeError`,
719                         // not selection error.
720                         span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
721                     }
722
723                     ty::Predicate::RegionOutlives(ref predicate) => {
724                         let predicate = self.resolve_vars_if_possible(predicate);
725                         let err = self
726                             .region_outlives_predicate(&obligation.cause, &predicate)
727                             .err()
728                             .unwrap();
729                         struct_span_err!(
730                             self.tcx.sess,
731                             span,
732                             E0279,
733                             "the requirement `{}` is not satisfied (`{}`)",
734                             predicate,
735                             err,
736                         )
737                     }
738
739                     ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
740                         let predicate = self.resolve_vars_if_possible(&obligation.predicate);
741                         struct_span_err!(
742                             self.tcx.sess,
743                             span,
744                             E0280,
745                             "the requirement `{}` is not satisfied",
746                             predicate
747                         )
748                     }
749
750                     ty::Predicate::ObjectSafe(trait_def_id) => {
751                         let violations = object_safety_violations(self.tcx, trait_def_id);
752                         report_object_safety_error(self.tcx, span, trait_def_id, violations)
753                     }
754
755                     ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
756                         let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap();
757                         let closure_span = self
758                             .tcx
759                             .sess
760                             .source_map()
761                             .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap());
762                         let hir_id = self.tcx.hir().as_local_hir_id(closure_def_id).unwrap();
763                         let mut err = struct_span_err!(
764                             self.tcx.sess,
765                             closure_span,
766                             E0525,
767                             "expected a closure that implements the `{}` trait, \
768                              but this closure only implements `{}`",
769                             kind,
770                             found_kind
771                         );
772
773                         err.span_label(
774                             closure_span,
775                             format!("this closure implements `{}`, not `{}`", found_kind, kind),
776                         );
777                         err.span_label(
778                             obligation.cause.span,
779                             format!("the requirement to implement `{}` derives from here", kind),
780                         );
781
782                         // Additional context information explaining why the closure only implements
783                         // a particular trait.
784                         if let Some(tables) = self.in_progress_tables {
785                             let tables = tables.borrow();
786                             match (found_kind, tables.closure_kind_origins().get(hir_id)) {
787                                 (ty::ClosureKind::FnOnce, Some((span, name))) => {
788                                     err.span_label(
789                                         *span,
790                                         format!(
791                                             "closure is `FnOnce` because it moves the \
792                                          variable `{}` out of its environment",
793                                             name
794                                         ),
795                                     );
796                                 }
797                                 (ty::ClosureKind::FnMut, Some((span, name))) => {
798                                     err.span_label(
799                                         *span,
800                                         format!(
801                                             "closure is `FnMut` because it mutates the \
802                                          variable `{}` here",
803                                             name
804                                         ),
805                                     );
806                                 }
807                                 _ => {}
808                             }
809                         }
810
811                         err.emit();
812                         return;
813                     }
814
815                     ty::Predicate::WellFormed(ty) => {
816                         if !self.tcx.sess.opts.debugging_opts.chalk {
817                             // WF predicates cannot themselves make
818                             // errors. They can only block due to
819                             // ambiguity; otherwise, they always
820                             // degenerate into other obligations
821                             // (which may fail).
822                             span_bug!(span, "WF predicate not satisfied for {:?}", ty);
823                         } else {
824                             // FIXME: we'll need a better message which takes into account
825                             // which bounds actually failed to hold.
826                             self.tcx.sess.struct_span_err(
827                                 span,
828                                 &format!("the type `{}` is not well-formed (chalk)", ty),
829                             )
830                         }
831                     }
832
833                     ty::Predicate::ConstEvaluatable(..) => {
834                         // Errors for `ConstEvaluatable` predicates show up as
835                         // `SelectionError::ConstEvalFailure`,
836                         // not `Unimplemented`.
837                         span_bug!(
838                             span,
839                             "const-evaluatable requirement gave wrong error: `{:?}`",
840                             obligation
841                         )
842                     }
843                 }
844             }
845
846             OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => {
847                 let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref);
848                 let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref);
849
850                 if expected_trait_ref.self_ty().references_error() {
851                     return;
852                 }
853
854                 let found_trait_ty = found_trait_ref.self_ty();
855
856                 let found_did = match found_trait_ty.kind {
857                     ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
858                     ty::Adt(def, _) => Some(def.did),
859                     _ => None,
860                 };
861
862                 let found_span = found_did
863                     .and_then(|did| self.tcx.hir().span_if_local(did))
864                     .map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
865
866                 if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) {
867                     // We check closures twice, with obligations flowing in different directions,
868                     // but we want to complain about them only once.
869                     return;
870                 }
871
872                 self.reported_closure_mismatch.borrow_mut().insert((span, found_span));
873
874                 let found = match found_trait_ref.skip_binder().substs.type_at(1).kind {
875                     ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
876                     _ => vec![ArgKind::empty()],
877                 };
878
879                 let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
880                 let expected = match expected_ty.kind {
881                     ty::Tuple(ref tys) => tys
882                         .iter()
883                         .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span)))
884                         .collect(),
885                     _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())],
886                 };
887
888                 if found.len() == expected.len() {
889                     self.report_closure_arg_mismatch(
890                         span,
891                         found_span,
892                         found_trait_ref,
893                         expected_trait_ref,
894                     )
895                 } else {
896                     let (closure_span, found) = found_did
897                         .and_then(|did| self.tcx.hir().get_if_local(did))
898                         .map(|node| {
899                             let (found_span, found) = self.get_fn_like_arguments(node);
900                             (Some(found_span), found)
901                         })
902                         .unwrap_or((found_span, found));
903
904                     self.report_arg_count_mismatch(
905                         span,
906                         closure_span,
907                         expected,
908                         found,
909                         found_trait_ty.is_closure(),
910                     )
911                 }
912             }
913
914             TraitNotObjectSafe(did) => {
915                 let violations = object_safety_violations(self.tcx, did);
916                 report_object_safety_error(self.tcx, span, did, violations)
917             }
918
919             ConstEvalFailure(ErrorHandled::TooGeneric) => {
920                 // In this instance, we have a const expression containing an unevaluated
921                 // generic parameter. We have no idea whether this expression is valid or
922                 // not (e.g. it might result in an error), but we don't want to just assume
923                 // that it's okay, because that might result in post-monomorphisation time
924                 // errors. The onus is really on the caller to provide values that it can
925                 // prove are well-formed.
926                 let mut err = self
927                     .tcx
928                     .sess
929                     .struct_span_err(span, "constant expression depends on a generic parameter");
930                 // FIXME(const_generics): we should suggest to the user how they can resolve this
931                 // issue. However, this is currently not actually possible
932                 // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
933                 err.note("this may fail depending on what value the parameter takes");
934                 err
935             }
936
937             // Already reported in the query.
938             ConstEvalFailure(ErrorHandled::Reported) => {
939                 self.tcx
940                     .sess
941                     .delay_span_bug(span, &format!("constant in type had an ignored error"));
942                 return;
943             }
944
945             Overflow => {
946                 bug!("overflow should be handled before the `report_selection_error` path");
947             }
948         };
949
950         self.note_obligation_cause(&mut err, obligation);
951         self.point_at_returns_when_relevant(&mut err, &obligation);
952
953         err.emit();
954     }
955
956     /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
957     /// with the same path as `trait_ref`, a help message about
958     /// a probable version mismatch is added to `err`
959     fn note_version_mismatch(
960         &self,
961         err: &mut DiagnosticBuilder<'_>,
962         trait_ref: &ty::PolyTraitRef<'tcx>,
963     ) {
964         let get_trait_impl = |trait_def_id| {
965             let mut trait_impl = None;
966             self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| {
967                 if trait_impl.is_none() {
968                     trait_impl = Some(impl_def_id);
969                 }
970             });
971             trait_impl
972         };
973         let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
974         let all_traits = self.tcx.all_traits(LOCAL_CRATE);
975         let traits_with_same_path: std::collections::BTreeSet<_> = all_traits
976             .iter()
977             .filter(|trait_def_id| **trait_def_id != trait_ref.def_id())
978             .filter(|trait_def_id| self.tcx.def_path_str(**trait_def_id) == required_trait_path)
979             .collect();
980         for trait_with_same_path in traits_with_same_path {
981             if let Some(impl_def_id) = get_trait_impl(*trait_with_same_path) {
982                 let impl_span = self.tcx.def_span(impl_def_id);
983                 err.span_help(impl_span, "trait impl with same name found");
984                 let trait_crate = self.tcx.crate_name(trait_with_same_path.krate);
985                 let crate_msg = format!(
986                     "perhaps two different versions of crate `{}` are being used?",
987                     trait_crate
988                 );
989                 err.note(&crate_msg);
990             }
991         }
992     }
993
994     fn mk_obligation_for_def_id(
995         &self,
996         def_id: DefId,
997         output_ty: Ty<'tcx>,
998         cause: ObligationCause<'tcx>,
999         param_env: ty::ParamEnv<'tcx>,
1000     ) -> PredicateObligation<'tcx> {
1001         let new_trait_ref =
1002             ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) };
1003         Obligation::new(cause, param_env, new_trait_ref.without_const().to_predicate())
1004     }
1005 }
1006
1007 pub fn recursive_type_with_infinite_size_error(
1008     tcx: TyCtxt<'tcx>,
1009     type_def_id: DefId,
1010 ) -> DiagnosticBuilder<'tcx> {
1011     assert!(type_def_id.is_local());
1012     let span = tcx.hir().span_if_local(type_def_id).unwrap();
1013     let span = tcx.sess.source_map().def_span(span);
1014     let mut err = struct_span_err!(
1015         tcx.sess,
1016         span,
1017         E0072,
1018         "recursive type `{}` has infinite size",
1019         tcx.def_path_str(type_def_id)
1020     );
1021     err.span_label(span, "recursive type has infinite size");
1022     err.help(&format!(
1023         "insert indirection (e.g., a `Box`, `Rc`, or `&`) \
1024                            at some point to make `{}` representable",
1025         tcx.def_path_str(type_def_id)
1026     ));
1027     err
1028 }
1029
1030 pub fn report_object_safety_error(
1031     tcx: TyCtxt<'tcx>,
1032     span: Span,
1033     trait_def_id: DefId,
1034     violations: Vec<ObjectSafetyViolation>,
1035 ) -> DiagnosticBuilder<'tcx> {
1036     let trait_str = tcx.def_path_str(trait_def_id);
1037     let span = tcx.sess.source_map().def_span(span);
1038     let mut err = struct_span_err!(
1039         tcx.sess,
1040         span,
1041         E0038,
1042         "the trait `{}` cannot be made into an object",
1043         trait_str
1044     );
1045     err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
1046
1047     let mut reported_violations = FxHashSet::default();
1048     for violation in violations {
1049         if let ObjectSafetyViolation::SizedSelf(sp) = &violation {
1050             if !sp.is_empty() {
1051                 // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations
1052                 // with a `Span`.
1053                 reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into()));
1054             }
1055         }
1056         if reported_violations.insert(violation.clone()) {
1057             let spans = violation.spans();
1058             if spans.is_empty() {
1059                 err.note(&violation.error_msg());
1060             } else {
1061                 for span in spans {
1062                     err.span_label(span, violation.error_msg());
1063                 }
1064             }
1065         }
1066     }
1067
1068     if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
1069         // Avoid emitting error caused by non-existing method (#58734)
1070         err.cancel();
1071     }
1072
1073     err
1074 }
1075
1076 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1077     fn maybe_report_ambiguity(
1078         &self,
1079         obligation: &PredicateObligation<'tcx>,
1080         body_id: Option<hir::BodyId>,
1081     ) {
1082         // Unable to successfully determine, probably means
1083         // insufficient type information, but could mean
1084         // ambiguous impls. The latter *ought* to be a
1085         // coherence violation, so we don't report it here.
1086
1087         let predicate = self.resolve_vars_if_possible(&obligation.predicate);
1088         let span = obligation.cause.span;
1089
1090         debug!(
1091             "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})",
1092             predicate, obligation, body_id, obligation.cause.code,
1093         );
1094
1095         // Ambiguity errors are often caused as fallout from earlier
1096         // errors. So just ignore them if this infcx is tainted.
1097         if self.is_tainted_by_errors() {
1098             return;
1099         }
1100
1101         let mut err = match predicate {
1102             ty::Predicate::Trait(ref data, _) => {
1103                 let trait_ref = data.to_poly_trait_ref();
1104                 let self_ty = trait_ref.self_ty();
1105                 debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
1106
1107                 if predicate.references_error() {
1108                     return;
1109                 }
1110                 // Typically, this ambiguity should only happen if
1111                 // there are unresolved type inference variables
1112                 // (otherwise it would suggest a coherence
1113                 // failure). But given #21974 that is not necessarily
1114                 // the case -- we can have multiple where clauses that
1115                 // are only distinguished by a region, which results
1116                 // in an ambiguity even when all types are fully
1117                 // known, since we don't dispatch based on region
1118                 // relationships.
1119
1120                 // This is kind of a hack: it frequently happens that some earlier
1121                 // error prevents types from being fully inferred, and then we get
1122                 // a bunch of uninteresting errors saying something like "<generic
1123                 // #0> doesn't implement Sized".  It may even be true that we
1124                 // could just skip over all checks where the self-ty is an
1125                 // inference variable, but I was afraid that there might be an
1126                 // inference variable created, registered as an obligation, and
1127                 // then never forced by writeback, and hence by skipping here we'd
1128                 // be ignoring the fact that we don't KNOW the type works
1129                 // out. Though even that would probably be harmless, given that
1130                 // we're only talking about builtin traits, which are known to be
1131                 // inhabited. We used to check for `self.tcx.sess.has_errors()` to
1132                 // avoid inundating the user with unnecessary errors, but we now
1133                 // check upstream for type errors and dont add the obligations to
1134                 // begin with in those cases.
1135                 if self
1136                     .tcx
1137                     .lang_items()
1138                     .sized_trait()
1139                     .map_or(false, |sized_id| sized_id == trait_ref.def_id())
1140                 {
1141                     self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
1142                     return;
1143                 }
1144                 let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
1145                 err.note(&format!("cannot resolve `{}`", predicate));
1146                 if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
1147                     self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
1148                 } else if let (
1149                     Ok(ref snippet),
1150                     ObligationCauseCode::BindingObligation(ref def_id, _),
1151                 ) =
1152                     (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code)
1153                 {
1154                     let generics = self.tcx.generics_of(*def_id);
1155                     if !generics.params.is_empty() && !snippet.ends_with('>') {
1156                         // FIXME: To avoid spurious suggestions in functions where type arguments
1157                         // where already supplied, we check the snippet to make sure it doesn't
1158                         // end with a turbofish. Ideally we would have access to a `PathSegment`
1159                         // instead. Otherwise we would produce the following output:
1160                         //
1161                         // error[E0283]: type annotations needed
1162                         //   --> $DIR/issue-54954.rs:3:24
1163                         //    |
1164                         // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
1165                         //    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
1166                         //    |                        |
1167                         //    |                        cannot infer type
1168                         //    |                        help: consider specifying the type argument
1169                         //    |                        in the function call:
1170                         //    |                        `Tt::const_val::<[i8; 123]>::<T>`
1171                         // ...
1172                         // LL |     const fn const_val<T: Sized>() -> usize {
1173                         //    |              --------- - required by this bound in `Tt::const_val`
1174                         //    |
1175                         //    = note: cannot resolve `_: Tt`
1176
1177                         err.span_suggestion(
1178                             span,
1179                             &format!(
1180                                 "consider specifying the type argument{} in the function call",
1181                                 if generics.params.len() > 1 { "s" } else { "" },
1182                             ),
1183                             format!(
1184                                 "{}::<{}>",
1185                                 snippet,
1186                                 generics
1187                                     .params
1188                                     .iter()
1189                                     .map(|p| p.name.to_string())
1190                                     .collect::<Vec<String>>()
1191                                     .join(", ")
1192                             ),
1193                             Applicability::HasPlaceholders,
1194                         );
1195                     }
1196                 }
1197                 err
1198             }
1199
1200             ty::Predicate::WellFormed(ty) => {
1201                 // Same hacky approach as above to avoid deluging user
1202                 // with error messages.
1203                 if ty.references_error() || self.tcx.sess.has_errors() {
1204                     return;
1205                 }
1206                 self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
1207             }
1208
1209             ty::Predicate::Subtype(ref data) => {
1210                 if data.references_error() || self.tcx.sess.has_errors() {
1211                     // no need to overload user in such cases
1212                     return;
1213                 }
1214                 let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
1215                 // both must be type variables, or the other would've been instantiated
1216                 assert!(a.is_ty_var() && b.is_ty_var());
1217                 self.need_type_info_err(body_id, span, a, ErrorCode::E0282)
1218             }
1219             ty::Predicate::Projection(ref data) => {
1220                 let trait_ref = data.to_poly_trait_ref(self.tcx);
1221                 let self_ty = trait_ref.self_ty();
1222                 if predicate.references_error() {
1223                     return;
1224                 }
1225                 let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
1226                 err.note(&format!("cannot resolve `{}`", predicate));
1227                 err
1228             }
1229
1230             _ => {
1231                 if self.tcx.sess.has_errors() {
1232                     return;
1233                 }
1234                 let mut err = struct_span_err!(
1235                     self.tcx.sess,
1236                     span,
1237                     E0284,
1238                     "type annotations needed: cannot resolve `{}`",
1239                     predicate,
1240                 );
1241                 err.span_label(span, &format!("cannot resolve `{}`", predicate));
1242                 err
1243             }
1244         };
1245         self.note_obligation_cause(&mut err, obligation);
1246         err.emit();
1247     }
1248
1249     /// Returns `true` if the trait predicate may apply for *some* assignment
1250     /// to the type parameters.
1251     fn predicate_can_apply(
1252         &self,
1253         param_env: ty::ParamEnv<'tcx>,
1254         pred: ty::PolyTraitRef<'tcx>,
1255     ) -> bool {
1256         struct ParamToVarFolder<'a, 'tcx> {
1257             infcx: &'a InferCtxt<'a, 'tcx>,
1258             var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>,
1259         }
1260
1261         impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> {
1262             fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
1263                 self.infcx.tcx
1264             }
1265
1266             fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1267                 if let ty::Param(ty::ParamTy { name, .. }) = ty.kind {
1268                     let infcx = self.infcx;
1269                     self.var_map.entry(ty).or_insert_with(|| {
1270                         infcx.next_ty_var(TypeVariableOrigin {
1271                             kind: TypeVariableOriginKind::TypeParameterDefinition(name, None),
1272                             span: DUMMY_SP,
1273                         })
1274                     })
1275                 } else {
1276                     ty.super_fold_with(self)
1277                 }
1278             }
1279         }
1280
1281         self.probe(|_| {
1282             let mut selcx = SelectionContext::new(self);
1283
1284             let cleaned_pred =
1285                 pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
1286
1287             let cleaned_pred = super::project::normalize(
1288                 &mut selcx,
1289                 param_env,
1290                 ObligationCause::dummy(),
1291                 &cleaned_pred,
1292             )
1293             .value;
1294
1295             let obligation = Obligation::new(
1296                 ObligationCause::dummy(),
1297                 param_env,
1298                 cleaned_pred.without_const().to_predicate(),
1299             );
1300
1301             self.predicate_may_hold(&obligation)
1302         })
1303     }
1304
1305     fn note_obligation_cause(
1306         &self,
1307         err: &mut DiagnosticBuilder<'_>,
1308         obligation: &PredicateObligation<'tcx>,
1309     ) {
1310         // First, attempt to add note to this error with an async-await-specific
1311         // message, and fall back to regular note otherwise.
1312         if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
1313             self.note_obligation_cause_code(
1314                 err,
1315                 &obligation.predicate,
1316                 &obligation.cause.code,
1317                 &mut vec![],
1318             );
1319         }
1320     }
1321
1322     fn is_recursive_obligation(
1323         &self,
1324         obligated_types: &mut Vec<&ty::TyS<'tcx>>,
1325         cause_code: &ObligationCauseCode<'tcx>,
1326     ) -> bool {
1327         if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
1328             let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
1329
1330             if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) {
1331                 return true;
1332             }
1333         }
1334         false
1335     }
1336 }
1337
1338 /// Summarizes information
1339 #[derive(Clone)]
1340 pub enum ArgKind {
1341     /// An argument of non-tuple type. Parameters are (name, ty)
1342     Arg(String, String),
1343
1344     /// An argument of tuple type. For a "found" argument, the span is
1345     /// the locationo in the source of the pattern. For a "expected"
1346     /// argument, it will be None. The vector is a list of (name, ty)
1347     /// strings for the components of the tuple.
1348     Tuple(Option<Span>, Vec<(String, String)>),
1349 }
1350
1351 impl ArgKind {
1352     fn empty() -> ArgKind {
1353         ArgKind::Arg("_".to_owned(), "_".to_owned())
1354     }
1355
1356     /// Creates an `ArgKind` from the expected type of an
1357     /// argument. It has no name (`_`) and an optional source span.
1358     pub fn from_expected_ty(t: Ty<'_>, span: Option<Span>) -> ArgKind {
1359         match t.kind {
1360             ty::Tuple(ref tys) => ArgKind::Tuple(
1361                 span,
1362                 tys.iter().map(|ty| ("_".to_owned(), ty.to_string())).collect::<Vec<_>>(),
1363             ),
1364             _ => ArgKind::Arg("_".to_owned(), t.to_string()),
1365         }
1366     }
1367 }
1368
1369 /// Suggest restricting a type param with a new bound.
1370 pub fn suggest_constraining_type_param(
1371     generics: &hir::Generics<'_>,
1372     err: &mut DiagnosticBuilder<'_>,
1373     param_name: &str,
1374     constraint: &str,
1375     source_map: &SourceMap,
1376     span: Span,
1377 ) -> bool {
1378     let restrict_msg = "consider further restricting this bound";
1379     if let Some(param) =
1380         generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next()
1381     {
1382         if param_name.starts_with("impl ") {
1383             // `impl Trait` in argument:
1384             // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
1385             err.span_suggestion(
1386                 param.span,
1387                 restrict_msg,
1388                 // `impl CurrentTrait + MissingTrait`
1389                 format!("{} + {}", param_name, constraint),
1390                 Applicability::MachineApplicable,
1391             );
1392         } else if generics.where_clause.predicates.is_empty() && param.bounds.is_empty() {
1393             // If there are no bounds whatsoever, suggest adding a constraint
1394             // to the type parameter:
1395             // `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
1396             err.span_suggestion(
1397                 param.span,
1398                 "consider restricting this bound",
1399                 format!("{}: {}", param_name, constraint),
1400                 Applicability::MachineApplicable,
1401             );
1402         } else if !generics.where_clause.predicates.is_empty() {
1403             // There is a `where` clause, so suggest expanding it:
1404             // `fn foo<T>(t: T) where T: Debug {}` →
1405             // `fn foo<T>(t: T) where T: Debug, T: Trait {}`
1406             err.span_suggestion(
1407                 generics.where_clause.span().unwrap().shrink_to_hi(),
1408                 &format!("consider further restricting type parameter `{}`", param_name),
1409                 format!(", {}: {}", param_name, constraint),
1410                 Applicability::MachineApplicable,
1411             );
1412         } else {
1413             // If there is no `where` clause lean towards constraining to the
1414             // type parameter:
1415             // `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
1416             // `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
1417             let sp = param.span.with_hi(span.hi());
1418             let span = source_map.span_through_char(sp, ':');
1419             if sp != param.span && sp != span {
1420                 // Only suggest if we have high certainty that the span
1421                 // covers the colon in `foo<T: Trait>`.
1422                 err.span_suggestion(
1423                     span,
1424                     restrict_msg,
1425                     format!("{}: {} + ", param_name, constraint),
1426                     Applicability::MachineApplicable,
1427                 );
1428             } else {
1429                 err.span_label(
1430                     param.span,
1431                     &format!("consider adding a `where {}: {}` bound", param_name, constraint),
1432                 );
1433             }
1434         }
1435         return true;
1436     }
1437     false
1438 }