]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/error_reporting.rs
Only warn about unused `mut` in user-written code
[rust.git] / src / librustc / traits / error_reporting.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use super::{
12     FulfillmentError,
13     FulfillmentErrorCode,
14     MismatchedProjectionTypes,
15     Obligation,
16     ObligationCause,
17     ObligationCauseCode,
18     OnUnimplementedDirective,
19     OnUnimplementedNote,
20     OutputTypeParameterMismatch,
21     TraitNotObjectSafe,
22     ConstEvalFailure,
23     PredicateObligation,
24     SelectionContext,
25     SelectionError,
26     ObjectSafetyViolation,
27     Overflow,
28 };
29
30 use errors::{Applicability, DiagnosticBuilder};
31 use hir;
32 use hir::Node;
33 use hir::def_id::DefId;
34 use infer::{self, InferCtxt};
35 use infer::type_variable::TypeVariableOrigin;
36 use std::fmt;
37 use std::iter;
38 use syntax::ast;
39 use session::DiagnosticMessageId;
40 use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
41 use ty::GenericParamDefKind;
42 use ty::error::ExpectedFound;
43 use ty::fast_reject;
44 use ty::fold::TypeFolder;
45 use ty::subst::Subst;
46 use ty::SubtypePredicate;
47 use util::nodemap::{FxHashMap, FxHashSet};
48
49 use syntax_pos::{DUMMY_SP, Span};
50
51 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
52     pub fn report_fulfillment_errors(&self,
53                                      errors: &[FulfillmentError<'tcx>],
54                                      body_id: Option<hir::BodyId>,
55                                      fallback_has_occurred: bool) {
56         #[derive(Debug)]
57         struct ErrorDescriptor<'tcx> {
58             predicate: ty::Predicate<'tcx>,
59             index: Option<usize>, // None if this is an old error
60         }
61
62         let mut error_map: FxHashMap<_, Vec<_>> =
63             self.reported_trait_errors.borrow().iter().map(|(&span, predicates)| {
64                 (span, predicates.iter().map(|predicate| ErrorDescriptor {
65                     predicate: predicate.clone(),
66                     index: None
67                 }).collect())
68             }).collect();
69
70         for (index, error) in errors.iter().enumerate() {
71             error_map.entry(error.obligation.cause.span).or_default().push(
72                 ErrorDescriptor {
73                     predicate: error.obligation.predicate.clone(),
74                     index: Some(index)
75                 });
76
77             self.reported_trait_errors.borrow_mut()
78                 .entry(error.obligation.cause.span).or_default()
79                 .push(error.obligation.predicate.clone());
80         }
81
82         // We do this in 2 passes because we want to display errors in order, tho
83         // maybe it *is* better to sort errors by span or something.
84         let mut is_suppressed = vec![false; errors.len()];
85         for (_, error_set) in error_map.iter() {
86             // We want to suppress "duplicate" errors with the same span.
87             for error in error_set {
88                 if let Some(index) = error.index {
89                     // Suppress errors that are either:
90                     // 1) strictly implied by another error.
91                     // 2) implied by an error with a smaller index.
92                     for error2 in error_set {
93                         if error2.index.map_or(false, |index2| is_suppressed[index2]) {
94                             // Avoid errors being suppressed by already-suppressed
95                             // errors, to prevent all errors from being suppressed
96                             // at once.
97                             continue
98                         }
99
100                         if self.error_implies(&error2.predicate, &error.predicate) &&
101                             !(error2.index >= error.index &&
102                               self.error_implies(&error.predicate, &error2.predicate))
103                         {
104                             info!("skipping {:?} (implied by {:?})", error, error2);
105                             is_suppressed[index] = true;
106                             break
107                         }
108                     }
109                 }
110             }
111         }
112
113         for (error, suppressed) in errors.iter().zip(is_suppressed) {
114             if !suppressed {
115                 self.report_fulfillment_error(error, body_id, fallback_has_occurred);
116             }
117         }
118     }
119
120     // returns if `cond` not occurring implies that `error` does not occur - i.e. that
121     // `error` occurring implies that `cond` occurs.
122     fn error_implies(&self,
123                      cond: &ty::Predicate<'tcx>,
124                      error: &ty::Predicate<'tcx>)
125                      -> bool
126     {
127         if cond == error {
128             return true
129         }
130
131         let (cond, error) = match (cond, error) {
132             (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error))
133                 => (cond, error),
134             _ => {
135                 // FIXME: make this work in other cases too.
136                 return false
137             }
138         };
139
140         for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) {
141             if let ty::Predicate::Trait(implication) = implication {
142                 let error = error.to_poly_trait_ref();
143                 let implication = implication.to_poly_trait_ref();
144                 // FIXME: I'm just not taking associated types at all here.
145                 // Eventually I'll need to implement param-env-aware
146                 // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
147                 let param_env = ty::ParamEnv::empty();
148                 if self.can_sub(param_env, error, implication).is_ok() {
149                     debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
150                     return true
151                 }
152             }
153         }
154
155         false
156     }
157
158     fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
159                                 body_id: Option<hir::BodyId>,
160                                 fallback_has_occurred: bool) {
161         debug!("report_fulfillment_errors({:?})", error);
162         match error.code {
163             FulfillmentErrorCode::CodeSelectionError(ref e) => {
164                 self.report_selection_error(&error.obligation, e, fallback_has_occurred);
165             }
166             FulfillmentErrorCode::CodeProjectionError(ref e) => {
167                 self.report_projection_error(&error.obligation, e);
168             }
169             FulfillmentErrorCode::CodeAmbiguity => {
170                 self.maybe_report_ambiguity(&error.obligation, body_id);
171             }
172             FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
173                 self.report_mismatched_types(&error.obligation.cause,
174                                              expected_found.expected,
175                                              expected_found.found,
176                                              err.clone())
177                     .emit();
178             }
179         }
180     }
181
182     fn report_projection_error(&self,
183                                obligation: &PredicateObligation<'tcx>,
184                                error: &MismatchedProjectionTypes<'tcx>)
185     {
186         let predicate =
187             self.resolve_type_vars_if_possible(&obligation.predicate);
188
189         if predicate.references_error() {
190             return
191         }
192
193         self.probe(|_| {
194             let err_buf;
195             let mut err = &error.err;
196             let mut values = None;
197
198             // try to find the mismatched types to report the error with.
199             //
200             // this can fail if the problem was higher-ranked, in which
201             // cause I have no idea for a good error message.
202             if let ty::Predicate::Projection(ref data) = predicate {
203                 let mut selcx = SelectionContext::new(self);
204                 let (data, _) = self.replace_late_bound_regions_with_fresh_var(
205                     obligation.cause.span,
206                     infer::LateBoundRegionConversionTime::HigherRankedType,
207                     data);
208                 let mut obligations = vec![];
209                 let normalized_ty = super::normalize_projection_type(
210                     &mut selcx,
211                     obligation.param_env,
212                     data.projection_ty,
213                     obligation.cause.clone(),
214                     0,
215                     &mut obligations
216                 );
217                 if let Err(error) = self.at(&obligation.cause, obligation.param_env)
218                                         .eq(normalized_ty, data.ty) {
219                     values = Some(infer::ValuePairs::Types(ExpectedFound {
220                         expected: normalized_ty,
221                         found: data.ty,
222                     }));
223                     err_buf = error;
224                     err = &err_buf;
225                 }
226             }
227
228             let msg = format!("type mismatch resolving `{}`", predicate);
229             let error_id = (DiagnosticMessageId::ErrorId(271),
230                             Some(obligation.cause.span), msg.clone());
231             let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
232             if fresh {
233                 let mut diag = struct_span_err!(
234                     self.tcx.sess, obligation.cause.span, E0271,
235                     "type mismatch resolving `{}`", predicate
236                 );
237                 self.note_type_err(&mut diag, &obligation.cause, None, values, err);
238                 self.note_obligation_cause(&mut diag, obligation);
239                 diag.emit();
240             }
241         });
242     }
243
244     fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
245         /// returns the fuzzy category of a given type, or None
246         /// if the type can be equated to any type.
247         fn type_category<'tcx>(t: Ty<'tcx>) -> Option<u32> {
248             match t.sty {
249                 ty::Bool => Some(0),
250                 ty::Char => Some(1),
251                 ty::Str => Some(2),
252                 ty::Int(..) | ty::Uint(..) | ty::Infer(ty::IntVar(..)) => Some(3),
253                 ty::Float(..) | ty::Infer(ty::FloatVar(..)) => Some(4),
254                 ty::Ref(..) | ty::RawPtr(..) => Some(5),
255                 ty::Array(..) | ty::Slice(..) => Some(6),
256                 ty::FnDef(..) | ty::FnPtr(..) => Some(7),
257                 ty::Dynamic(..) => Some(8),
258                 ty::Closure(..) => Some(9),
259                 ty::Tuple(..) => Some(10),
260                 ty::Projection(..) => Some(11),
261                 ty::Param(..) => Some(12),
262                 ty::Opaque(..) => Some(13),
263                 ty::Never => Some(14),
264                 ty::Adt(adt, ..) => match adt.adt_kind() {
265                     AdtKind::Struct => Some(15),
266                     AdtKind::Union => Some(16),
267                     AdtKind::Enum => Some(17),
268                 },
269                 ty::Generator(..) => Some(18),
270                 ty::Foreign(..) => Some(19),
271                 ty::GeneratorWitness(..) => Some(20),
272                 ty::Infer(..) | ty::Error => None
273             }
274         }
275
276         match (type_category(a), type_category(b)) {
277             (Some(cat_a), Some(cat_b)) => match (&a.sty, &b.sty) {
278                 (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b,
279                 _ => cat_a == cat_b
280             },
281             // infer and error can be equated to all types
282             _ => true
283         }
284     }
285
286     fn impl_similar_to(&self,
287                        trait_ref: ty::PolyTraitRef<'tcx>,
288                        obligation: &PredicateObligation<'tcx>)
289                        -> Option<DefId>
290     {
291         let tcx = self.tcx;
292         let param_env = obligation.param_env;
293         let trait_ref = tcx.erase_late_bound_regions(&trait_ref);
294         let trait_self_ty = trait_ref.self_ty();
295
296         let mut self_match_impls = vec![];
297         let mut fuzzy_match_impls = vec![];
298
299         self.tcx.for_each_relevant_impl(
300             trait_ref.def_id, trait_self_ty, |def_id| {
301                 let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
302                 let impl_trait_ref = tcx
303                     .impl_trait_ref(def_id)
304                     .unwrap()
305                     .subst(tcx, impl_substs);
306
307                 let impl_self_ty = impl_trait_ref.self_ty();
308
309                 if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) {
310                     self_match_impls.push(def_id);
311
312                     if trait_ref.substs.types().skip(1)
313                         .zip(impl_trait_ref.substs.types().skip(1))
314                         .all(|(u,v)| self.fuzzy_match_tys(u, v))
315                     {
316                         fuzzy_match_impls.push(def_id);
317                     }
318                 }
319             });
320
321         let impl_def_id = if self_match_impls.len() == 1 {
322             self_match_impls[0]
323         } else if fuzzy_match_impls.len() == 1 {
324             fuzzy_match_impls[0]
325         } else {
326             return None
327         };
328
329         if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") {
330             Some(impl_def_id)
331         } else {
332             None
333         }
334     }
335
336     fn on_unimplemented_note(
337         &self,
338         trait_ref: ty::PolyTraitRef<'tcx>,
339         obligation: &PredicateObligation<'tcx>) ->
340         OnUnimplementedNote
341     {
342         let def_id = self.impl_similar_to(trait_ref, obligation)
343             .unwrap_or(trait_ref.def_id());
344         let trait_ref = *trait_ref.skip_binder();
345
346         let mut flags = vec![];
347         match obligation.cause.code {
348             ObligationCauseCode::BuiltinDerivedObligation(..) |
349             ObligationCauseCode::ImplDerivedObligation(..) => {}
350             _ => {
351                 // this is a "direct", user-specified, rather than derived,
352                 // obligation.
353                 flags.push(("direct".to_owned(), None));
354             }
355         }
356
357         if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
358             // FIXME: maybe also have some way of handling methods
359             // from other traits? That would require name resolution,
360             // which we might want to be some sort of hygienic.
361             //
362             // Currently I'm leaving it for what I need for `try`.
363             if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
364                 let method = self.tcx.item_name(item);
365                 flags.push(("from_method".to_owned(), None));
366                 flags.push(("from_method".to_owned(), Some(method.to_string())));
367             }
368         }
369
370         if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
371             flags.push(("from_desugaring".to_owned(), None));
372             flags.push(("from_desugaring".to_owned(), Some(k.name().to_string())));
373         }
374         let generics = self.tcx.generics_of(def_id);
375         let self_ty = trait_ref.self_ty();
376         // This is also included through the generics list as `Self`,
377         // but the parser won't allow you to use it
378         flags.push(("_Self".to_owned(), Some(self_ty.to_string())));
379         if let Some(def) = self_ty.ty_adt_def() {
380             // We also want to be able to select self's original
381             // signature with no type arguments resolved
382             flags.push(("_Self".to_owned(), Some(self.tcx.type_of(def.did).to_string())));
383         }
384
385         for param in generics.params.iter() {
386             let value = match param.kind {
387                 GenericParamDefKind::Type {..} => {
388                     trait_ref.substs[param.index as usize].to_string()
389                 },
390                 GenericParamDefKind::Lifetime => continue,
391             };
392             let name = param.name.to_string();
393             flags.push((name, Some(value)));
394         }
395
396         if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
397             flags.push(("crate_local".to_owned(), None));
398         }
399
400         if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
401             self.tcx, trait_ref.def_id, def_id
402         ) {
403             command.evaluate(self.tcx, trait_ref, &flags[..])
404         } else {
405             OnUnimplementedNote::empty()
406         }
407     }
408
409     fn find_similar_impl_candidates(&self,
410                                     trait_ref: ty::PolyTraitRef<'tcx>)
411                                     -> Vec<ty::TraitRef<'tcx>>
412     {
413         let simp = fast_reject::simplify_type(self.tcx,
414                                               trait_ref.skip_binder().self_ty(),
415                                               true);
416         let all_impls = self.tcx.all_impls(trait_ref.def_id());
417
418         match simp {
419             Some(simp) => all_impls.iter().filter_map(|&def_id| {
420                 let imp = self.tcx.impl_trait_ref(def_id).unwrap();
421                 let imp_simp = fast_reject::simplify_type(self.tcx,
422                                                           imp.self_ty(),
423                                                           true);
424                 if let Some(imp_simp) = imp_simp {
425                     if simp != imp_simp {
426                         return None
427                     }
428                 }
429
430                 Some(imp)
431             }).collect(),
432             None => all_impls.iter().map(|&def_id|
433                 self.tcx.impl_trait_ref(def_id).unwrap()
434             ).collect()
435         }
436     }
437
438     fn report_similar_impl_candidates(&self,
439                                       mut impl_candidates: Vec<ty::TraitRef<'tcx>>,
440                                       err: &mut DiagnosticBuilder)
441     {
442         if impl_candidates.is_empty() {
443             return;
444         }
445
446         let len = impl_candidates.len();
447         let end = if impl_candidates.len() <= 5 {
448             impl_candidates.len()
449         } else {
450             4
451         };
452
453         let normalize = |candidate| self.tcx.global_tcx().infer_ctxt().enter(|ref infcx| {
454             let normalized = infcx
455                 .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
456                 .normalize(candidate)
457                 .ok();
458             match normalized {
459                 Some(normalized) => format!("\n  {:?}", normalized.value),
460                 None => format!("\n  {:?}", candidate),
461             }
462         });
463
464         // Sort impl candidates so that ordering is consistent for UI tests.
465         let normalized_impl_candidates = &mut impl_candidates[0..end]
466             .iter()
467             .map(normalize)
468             .collect::<Vec<String>>();
469         normalized_impl_candidates.sort();
470
471         err.help(&format!("the following implementations were found:{}{}",
472                           normalized_impl_candidates.join(""),
473                           if len > 5 {
474                               format!("\nand {} others", len - 4)
475                           } else {
476                               String::new()
477                           }
478                           ));
479     }
480
481     /// Reports that an overflow has occurred and halts compilation. We
482     /// halt compilation unconditionally because it is important that
483     /// overflows never be masked -- they basically represent computations
484     /// whose result could not be truly determined and thus we can't say
485     /// if the program type checks or not -- and they are unusual
486     /// occurrences in any case.
487     pub fn report_overflow_error<T>(&self,
488                                     obligation: &Obligation<'tcx, T>,
489                                     suggest_increasing_limit: bool) -> !
490         where T: fmt::Display + TypeFoldable<'tcx>
491     {
492         let predicate =
493             self.resolve_type_vars_if_possible(&obligation.predicate);
494         let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
495                                        "overflow evaluating the requirement `{}`",
496                                        predicate);
497
498         if suggest_increasing_limit {
499             self.suggest_new_overflow_limit(&mut err);
500         }
501
502         self.note_obligation_cause(&mut err, obligation);
503
504         err.emit();
505         self.tcx.sess.abort_if_errors();
506         bug!();
507     }
508
509     /// Reports that a cycle was detected which led to overflow and halts
510     /// compilation. This is equivalent to `report_overflow_error` except
511     /// that we can give a more helpful error message (and, in particular,
512     /// we do not suggest increasing the overflow limit, which is not
513     /// going to help).
514     pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
515         let cycle = self.resolve_type_vars_if_possible(&cycle.to_owned());
516         assert!(cycle.len() > 0);
517
518         debug!("report_overflow_error_cycle: cycle={:?}", cycle);
519
520         self.report_overflow_error(&cycle[0], false);
521     }
522
523     pub fn report_extra_impl_obligation(&self,
524                                         error_span: Span,
525                                         item_name: ast::Name,
526                                         _impl_item_def_id: DefId,
527                                         trait_item_def_id: DefId,
528                                         requirement: &dyn fmt::Display)
529                                         -> DiagnosticBuilder<'tcx>
530     {
531         let msg = "impl has stricter requirements than trait";
532         let sp = self.tcx.sess.source_map().def_span(error_span);
533
534         let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg);
535
536         if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
537             let span = self.tcx.sess.source_map().def_span(trait_item_span);
538             err.span_label(span, format!("definition of `{}` from trait", item_name));
539         }
540
541         err.span_label(sp, format!("impl has extra requirement {}", requirement));
542
543         err
544     }
545
546
547     /// Get the parent trait chain start
548     fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
549         match code {
550             &ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
551                 let parent_trait_ref = self.resolve_type_vars_if_possible(
552                     &data.parent_trait_ref);
553                 match self.get_parent_trait_ref(&data.parent_code) {
554                     Some(t) => Some(t),
555                     None => Some(parent_trait_ref.skip_binder().self_ty().to_string()),
556                 }
557             }
558             _ => None,
559         }
560     }
561
562     pub fn report_selection_error(&self,
563                                   obligation: &PredicateObligation<'tcx>,
564                                   error: &SelectionError<'tcx>,
565                                   fallback_has_occurred: bool)
566     {
567         let span = obligation.cause.span;
568
569         let mut err = match *error {
570             SelectionError::Unimplemented => {
571                 if let ObligationCauseCode::CompareImplMethodObligation {
572                     item_name, impl_item_def_id, trait_item_def_id,
573                 } = obligation.cause.code {
574                     self.report_extra_impl_obligation(
575                         span,
576                         item_name,
577                         impl_item_def_id,
578                         trait_item_def_id,
579                         &format!("`{}`", obligation.predicate))
580                         .emit();
581                     return;
582                 }
583                 match obligation.predicate {
584                     ty::Predicate::Trait(ref trait_predicate) => {
585                         let trait_predicate =
586                             self.resolve_type_vars_if_possible(trait_predicate);
587
588                         if self.tcx.sess.has_errors() && trait_predicate.references_error() {
589                             return;
590                         }
591                         let trait_ref = trait_predicate.to_poly_trait_ref();
592                         let (post_message, pre_message) =
593                             self.get_parent_trait_ref(&obligation.cause.code)
594                                 .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
595                             .unwrap_or((String::new(), String::new()));
596
597                         let OnUnimplementedNote { message, label, note }
598                             = self.on_unimplemented_note(trait_ref, obligation);
599                         let have_alt_message = message.is_some() || label.is_some();
600
601                         let mut err = struct_span_err!(
602                             self.tcx.sess,
603                             span,
604                             E0277,
605                             "{}",
606                             message.unwrap_or_else(||
607                                 format!("the trait bound `{}` is not satisfied{}",
608                                          trait_ref.to_predicate(), post_message)
609                             ));
610
611                         let explanation =
612                             if obligation.cause.code == ObligationCauseCode::MainFunctionType {
613                                 "consider using `()`, or a `Result`".to_owned()
614                             } else {
615                                 format!("{}the trait `{}` is not implemented for `{}`",
616                                         pre_message,
617                                         trait_ref,
618                                         trait_ref.self_ty())
619                             };
620
621                         if let Some(ref s) = label {
622                             // If it has a custom "#[rustc_on_unimplemented]"
623                             // error message, let's display it as the label!
624                             err.span_label(span, s.as_str());
625                             err.help(&explanation);
626                         } else {
627                             err.span_label(span, explanation);
628                         }
629                         if let Some(ref s) = note {
630                             // If it has a custom "#[rustc_on_unimplemented]" note, let's display it
631                             err.note(s.as_str());
632                         }
633
634                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
635                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
636
637                         // Try to report a help message
638                         if !trait_ref.has_infer_types() &&
639                             self.predicate_can_apply(obligation.param_env, trait_ref) {
640                             // If a where-clause may be useful, remind the
641                             // user that they can add it.
642                             //
643                             // don't display an on-unimplemented note, as
644                             // these notes will often be of the form
645                             //     "the type `T` can't be frobnicated"
646                             // which is somewhat confusing.
647                             err.help(&format!("consider adding a `where {}` bound",
648                                               trait_ref.to_predicate()));
649                         } else if !have_alt_message {
650                             // Can't show anything else useful, try to find similar impls.
651                             let impl_candidates = self.find_similar_impl_candidates(trait_ref);
652                             self.report_similar_impl_candidates(impl_candidates, &mut err);
653                         }
654
655                         // If this error is due to `!: Trait` not implemented but `(): Trait` is
656                         // implemented, and fallback has occurred, then it could be due to a
657                         // variable that used to fallback to `()` now falling back to `!`. Issue a
658                         // note informing about the change in behaviour.
659                         if trait_predicate.skip_binder().self_ty().is_never()
660                             && fallback_has_occurred
661                         {
662                             let predicate = trait_predicate.map_bound(|mut trait_pred| {
663                                 trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
664                                     self.tcx.mk_unit(),
665                                     &trait_pred.trait_ref.substs[1..],
666                                 );
667                                 trait_pred
668                             });
669                             let unit_obligation = Obligation {
670                                 predicate: ty::Predicate::Trait(predicate),
671                                 .. obligation.clone()
672                             };
673                             if self.predicate_may_hold(&unit_obligation) {
674                                 err.note("the trait is implemented for `()`. \
675                                          Possibly this error has been caused by changes to \
676                                          Rust's type-inference algorithm \
677                                          (see: https://github.com/rust-lang/rust/issues/48950 \
678                                          for more info). Consider whether you meant to use the \
679                                          type `()` here instead.");
680                             }
681                         }
682
683                         err
684                     }
685
686                     ty::Predicate::Subtype(ref predicate) => {
687                         // Errors for Subtype predicates show up as
688                         // `FulfillmentErrorCode::CodeSubtypeError`,
689                         // not selection error.
690                         span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
691                     }
692
693                     ty::Predicate::RegionOutlives(ref predicate) => {
694                         let predicate = self.resolve_type_vars_if_possible(predicate);
695                         let err = self.region_outlives_predicate(&obligation.cause,
696                                                                  &predicate).err().unwrap();
697                         struct_span_err!(self.tcx.sess, span, E0279,
698                             "the requirement `{}` is not satisfied (`{}`)",
699                             predicate, err)
700                     }
701
702                     ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
703                         let predicate =
704                             self.resolve_type_vars_if_possible(&obligation.predicate);
705                         struct_span_err!(self.tcx.sess, span, E0280,
706                             "the requirement `{}` is not satisfied",
707                             predicate)
708                     }
709
710                     ty::Predicate::ObjectSafe(trait_def_id) => {
711                         let violations = self.tcx.object_safety_violations(trait_def_id);
712                         self.tcx.report_object_safety_error(span,
713                                                             trait_def_id,
714                                                             violations)
715                     }
716
717                     ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
718                         let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap();
719                         let closure_span = self.tcx.sess.source_map()
720                             .def_span(self.tcx.hir.span_if_local(closure_def_id).unwrap());
721                         let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
722                         let mut err = struct_span_err!(
723                             self.tcx.sess, closure_span, E0525,
724                             "expected a closure that implements the `{}` trait, \
725                              but this closure only implements `{}`",
726                             kind,
727                             found_kind);
728
729                         err.span_label(
730                             closure_span,
731                             format!("this closure implements `{}`, not `{}`", found_kind, kind));
732                         err.span_label(
733                             obligation.cause.span,
734                             format!("the requirement to implement `{}` derives from here", kind));
735
736                         // Additional context information explaining why the closure only implements
737                         // a particular trait.
738                         if let Some(tables) = self.in_progress_tables {
739                             let tables = tables.borrow();
740                             let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id);
741                             match (found_kind, tables.closure_kind_origins().get(closure_hir_id)) {
742                                 (ty::ClosureKind::FnOnce, Some((span, name))) => {
743                                     err.span_label(*span, format!(
744                                         "closure is `FnOnce` because it moves the \
745                                          variable `{}` out of its environment", name));
746                                 },
747                                 (ty::ClosureKind::FnMut, Some((span, name))) => {
748                                     err.span_label(*span, format!(
749                                         "closure is `FnMut` because it mutates the \
750                                          variable `{}` here", name));
751                                 },
752                                 _ => {}
753                             }
754                         }
755
756                         err.emit();
757                         return;
758                     }
759
760                     ty::Predicate::WellFormed(ty) => {
761                         // WF predicates cannot themselves make
762                         // errors. They can only block due to
763                         // ambiguity; otherwise, they always
764                         // degenerate into other obligations
765                         // (which may fail).
766                         span_bug!(span, "WF predicate not satisfied for {:?}", ty);
767                     }
768
769                     ty::Predicate::ConstEvaluatable(..) => {
770                         // Errors for `ConstEvaluatable` predicates show up as
771                         // `SelectionError::ConstEvalFailure`,
772                         // not `Unimplemented`.
773                         span_bug!(span,
774                             "const-evaluatable requirement gave wrong error: `{:?}`", obligation)
775                     }
776                 }
777             }
778
779             OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => {
780                 let found_trait_ref = self.resolve_type_vars_if_possible(&*found_trait_ref);
781                 let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
782
783                 if expected_trait_ref.self_ty().references_error() {
784                     return;
785                 }
786
787                 let found_trait_ty = found_trait_ref.self_ty();
788
789                 let found_did = match found_trait_ty.sty {
790                     ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
791                     ty::Adt(def, _) => Some(def.did),
792                     _ => None,
793                 };
794
795                 let found_span = found_did.and_then(|did|
796                     self.tcx.hir.span_if_local(did)
797                 ).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def
798
799                 let found = match found_trait_ref.skip_binder().substs.type_at(1).sty {
800                     ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
801                     _ => vec![ArgKind::empty()],
802                 };
803
804                 let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
805                     ty::Tuple(ref tys) => tys.iter()
806                         .map(|t| ArgKind::from_expected_ty(t, Some(span))).collect(),
807                     ref sty => vec![ArgKind::Arg("_".to_owned(), sty.to_string())],
808                 };
809
810                 if found.len() == expected.len() {
811                     self.report_closure_arg_mismatch(span,
812                                                      found_span,
813                                                      found_trait_ref,
814                                                      expected_trait_ref)
815                 } else {
816                     let (closure_span, found) = found_did
817                         .and_then(|did| self.tcx.hir.get_if_local(did))
818                         .map(|node| {
819                             let (found_span, found) = self.get_fn_like_arguments(node);
820                             (Some(found_span), found)
821                         }).unwrap_or((found_span, found));
822
823                     self.report_arg_count_mismatch(span,
824                                                    closure_span,
825                                                    expected,
826                                                    found,
827                                                    found_trait_ty.is_closure())
828                 }
829             }
830
831             TraitNotObjectSafe(did) => {
832                 let violations = self.tcx.object_safety_violations(did);
833                 self.tcx.report_object_safety_error(span, did, violations)
834             }
835
836             ConstEvalFailure(ref err) => {
837                 match err.struct_error(
838                     self.tcx.at(span),
839                     "could not evaluate constant expression",
840                 ) {
841                     Some(err) => err,
842                     None => {
843                         self.tcx.sess.delay_span_bug(span,
844                             &format!("constant in type had an ignored error: {:?}", err));
845                         return;
846                     }
847                 }
848             }
849
850             Overflow => {
851                 bug!("overflow should be handled before the `report_selection_error` path");
852             }
853         };
854         self.note_obligation_cause(&mut err, obligation);
855         err.emit();
856     }
857
858     /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
859     /// suggestion to borrow the initializer in order to use have a slice instead.
860     fn suggest_borrow_on_unsized_slice(&self,
861                                        code: &ObligationCauseCode<'tcx>,
862                                        err: &mut DiagnosticBuilder<'tcx>) {
863         if let &ObligationCauseCode::VariableType(node_id) = code {
864             let parent_node = self.tcx.hir.get_parent_node(node_id);
865             if let Some(Node::Local(ref local)) = self.tcx.hir.find(parent_node) {
866                 if let Some(ref expr) = local.init {
867                     if let hir::ExprKind::Index(_, _) = expr.node {
868                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
869                             err.span_suggestion_with_applicability(
870                                 expr.span,
871                                 "consider borrowing here",
872                                 format!("&{}", snippet),
873                                 Applicability::MachineApplicable
874                             );
875                         }
876                     }
877                 }
878             }
879         }
880     }
881
882     /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
883     /// suggest removing these references until we reach a type that implements the trait.
884     fn suggest_remove_reference(&self,
885                                 obligation: &PredicateObligation<'tcx>,
886                                 err: &mut DiagnosticBuilder<'tcx>,
887                                 trait_ref: &ty::Binder<ty::TraitRef<'tcx>>) {
888         let trait_ref = trait_ref.skip_binder();
889         let span = obligation.cause.span;
890
891         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
892             let refs_number = snippet.chars()
893                 .filter(|c| !c.is_whitespace())
894                 .take_while(|c| *c == '&')
895                 .count();
896
897             let mut trait_type = trait_ref.self_ty();
898
899             for refs_remaining in 0..refs_number {
900                 if let ty::Ref(_, t_type, _) = trait_type.sty {
901                     trait_type = t_type;
902
903                     let substs = self.tcx.mk_substs_trait(trait_type, &[]);
904                     let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs);
905                     let new_obligation = Obligation::new(ObligationCause::dummy(),
906                                                          obligation.param_env,
907                                                          new_trait_ref.to_predicate());
908
909                     if self.predicate_may_hold(&new_obligation) {
910                         let sp = self.tcx.sess.source_map()
911                             .span_take_while(span, |c| c.is_whitespace() || *c == '&');
912
913                         let remove_refs = refs_remaining + 1;
914                         let format_str = format!("consider removing {} leading `&`-references",
915                                                  remove_refs);
916
917                         err.span_suggestion_short_with_applicability(
918                             sp, &format_str, String::new(), Applicability::MachineApplicable
919                         );
920                         break;
921                     }
922                 } else {
923                     break;
924                 }
925             }
926         }
927     }
928
929     /// Given some node representing a fn-like thing in the HIR map,
930     /// returns a span and `ArgKind` information that describes the
931     /// arguments it expects. This can be supplied to
932     /// `report_arg_count_mismatch`.
933     pub fn get_fn_like_arguments(&self, node: Node) -> (Span, Vec<ArgKind>) {
934         match node {
935             Node::Expr(&hir::Expr {
936                 node: hir::ExprKind::Closure(_, ref _decl, id, span, _),
937                 ..
938             }) => {
939                 (self.tcx.sess.source_map().def_span(span), self.tcx.hir.body(id).arguments.iter()
940                     .map(|arg| {
941                         if let hir::Pat {
942                             node: hir::PatKind::Tuple(args, _),
943                             span,
944                             ..
945                         } = arg.pat.clone().into_inner() {
946                             ArgKind::Tuple(
947                                 Some(span),
948                                 args.iter().map(|pat| {
949                                     let snippet = self.tcx.sess.source_map()
950                                         .span_to_snippet(pat.span).unwrap();
951                                     (snippet, "_".to_owned())
952                                 }).collect::<Vec<_>>(),
953                             )
954                         } else {
955                             let name = self.tcx.sess.source_map()
956                                 .span_to_snippet(arg.pat.span).unwrap();
957                             ArgKind::Arg(name, "_".to_owned())
958                         }
959                     })
960                     .collect::<Vec<ArgKind>>())
961             }
962             Node::Item(&hir::Item {
963                 span,
964                 node: hir::ItemKind::Fn(ref decl, ..),
965                 ..
966             }) |
967             Node::ImplItem(&hir::ImplItem {
968                 span,
969                 node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _),
970                 ..
971             }) |
972             Node::TraitItem(&hir::TraitItem {
973                 span,
974                 node: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _),
975                 ..
976             }) => {
977                 (self.tcx.sess.source_map().def_span(span), decl.inputs.iter()
978                         .map(|arg| match arg.clone().node {
979                     hir::TyKind::Tup(ref tys) => ArgKind::Tuple(
980                         Some(arg.span),
981                         vec![("_".to_owned(), "_".to_owned()); tys.len()]
982                     ),
983                     _ => ArgKind::empty()
984                 }).collect::<Vec<ArgKind>>())
985             }
986             Node::Variant(&hir::Variant {
987                 span,
988                 node: hir::VariantKind {
989                     data: hir::VariantData::Tuple(ref fields, _),
990                     ..
991                 },
992                 ..
993             }) => {
994                 (self.tcx.sess.source_map().def_span(span),
995                  fields.iter().map(|field|
996                      ArgKind::Arg(field.ident.to_string(), "_".to_string())
997                  ).collect::<Vec<_>>())
998             }
999             Node::StructCtor(ref variant_data) => {
1000                 (self.tcx.sess.source_map().def_span(self.tcx.hir.span(variant_data.id())),
1001                  vec![ArgKind::empty(); variant_data.fields().len()])
1002             }
1003             _ => panic!("non-FnLike node found: {:?}", node),
1004         }
1005     }
1006
1007     /// Reports an error when the number of arguments needed by a
1008     /// trait match doesn't match the number that the expression
1009     /// provides.
1010     pub fn report_arg_count_mismatch(
1011         &self,
1012         span: Span,
1013         found_span: Option<Span>,
1014         expected_args: Vec<ArgKind>,
1015         found_args: Vec<ArgKind>,
1016         is_closure: bool,
1017     ) -> DiagnosticBuilder<'tcx> {
1018         let kind = if is_closure { "closure" } else { "function" };
1019
1020         let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {
1021             let arg_length = arguments.len();
1022             let distinct = match &other[..] {
1023                 &[ArgKind::Tuple(..)] => true,
1024                 _ => false,
1025             };
1026             match (arg_length, arguments.get(0)) {
1027                 (1, Some(&ArgKind::Tuple(_, ref fields))) => {
1028                     format!("a single {}-tuple as argument", fields.len())
1029                 }
1030                 _ => format!("{} {}argument{}",
1031                              arg_length,
1032                              if distinct && arg_length > 1 { "distinct " } else { "" },
1033                              if arg_length == 1 { "" } else { "s" }),
1034             }
1035         };
1036
1037         let expected_str = args_str(&expected_args, &found_args);
1038         let found_str = args_str(&found_args, &expected_args);
1039
1040         let mut err = struct_span_err!(
1041             self.tcx.sess,
1042             span,
1043             E0593,
1044             "{} is expected to take {}, but it takes {}",
1045             kind,
1046             expected_str,
1047             found_str,
1048         );
1049
1050         err.span_label(span, format!("expected {} that takes {}", kind, expected_str));
1051
1052         if let Some(found_span) = found_span {
1053             err.span_label(found_span, format!("takes {}", found_str));
1054
1055             // Suggest to take and ignore the arguments with expected_args_length `_`s if
1056             // found arguments is empty (assume the user just wants to ignore args in this case).
1057             // For example, if `expected_args_length` is 2, suggest `|_, _|`.
1058             if found_args.is_empty() && is_closure {
1059                 let underscores = iter::repeat("_")
1060                                       .take(expected_args.len())
1061                                       .collect::<Vec<_>>()
1062                                       .join(", ");
1063                 err.span_suggestion_with_applicability(
1064                     found_span,
1065                     &format!(
1066                         "consider changing the closure to take and ignore the expected argument{}",
1067                         if expected_args.len() < 2 {
1068                             ""
1069                         } else {
1070                             "s"
1071                         }
1072                     ),
1073                     format!("|{}|", underscores),
1074                     Applicability::MachineApplicable,
1075                 );
1076             }
1077
1078             if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] {
1079                 if fields.len() == expected_args.len() {
1080                     let sugg = fields.iter()
1081                         .map(|(name, _)| name.to_owned())
1082                         .collect::<Vec<String>>()
1083                         .join(", ");
1084                     err.span_suggestion_with_applicability(found_span,
1085                                                            "change the closure to take multiple \
1086                                                             arguments instead of a single tuple",
1087                                                            format!("|{}|", sugg),
1088                                                            Applicability::MachineApplicable);
1089                 }
1090             }
1091             if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
1092                 if fields.len() == found_args.len() && is_closure {
1093                     let sugg = format!(
1094                         "|({}){}|",
1095                         found_args.iter()
1096                             .map(|arg| match arg {
1097                                 ArgKind::Arg(name, _) => name.to_owned(),
1098                                 _ => "_".to_owned(),
1099                             })
1100                             .collect::<Vec<String>>()
1101                             .join(", "),
1102                         // add type annotations if available
1103                         if found_args.iter().any(|arg| match arg {
1104                             ArgKind::Arg(_, ty) => ty != "_",
1105                             _ => false,
1106                         }) {
1107                             format!(": ({})",
1108                                     fields.iter()
1109                                         .map(|(_, ty)| ty.to_owned())
1110                                         .collect::<Vec<String>>()
1111                                         .join(", "))
1112                         } else {
1113                             String::new()
1114                         },
1115                     );
1116                     err.span_suggestion_with_applicability(
1117                         found_span,
1118                         "change the closure to accept a tuple instead of \
1119                          individual arguments",
1120                         sugg,
1121                         Applicability::MachineApplicable
1122                     );
1123                 }
1124             }
1125         }
1126
1127         err
1128     }
1129
1130     fn report_closure_arg_mismatch(&self,
1131                            span: Span,
1132                            found_span: Option<Span>,
1133                            expected_ref: ty::PolyTraitRef<'tcx>,
1134                            found: ty::PolyTraitRef<'tcx>)
1135         -> DiagnosticBuilder<'tcx>
1136     {
1137         fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
1138                                                trait_ref: &ty::TraitRef<'tcx>) -> String {
1139             let inputs = trait_ref.substs.type_at(1);
1140             let sig = if let ty::Tuple(inputs) = inputs.sty {
1141                 tcx.mk_fn_sig(
1142                     inputs.iter().cloned(),
1143                     tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
1144                     false,
1145                     hir::Unsafety::Normal,
1146                     ::rustc_target::spec::abi::Abi::Rust
1147                 )
1148             } else {
1149                 tcx.mk_fn_sig(
1150                     ::std::iter::once(inputs),
1151                     tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
1152                     false,
1153                     hir::Unsafety::Normal,
1154                     ::rustc_target::spec::abi::Abi::Rust
1155                 )
1156             };
1157             ty::Binder::bind(sig).to_string()
1158         }
1159
1160         let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
1161         let mut err = struct_span_err!(self.tcx.sess, span, E0631,
1162                                        "type mismatch in {} arguments",
1163                                        if argument_is_closure { "closure" } else { "function" });
1164
1165         let found_str = format!(
1166             "expected signature of `{}`",
1167             build_fn_sig_string(self.tcx, found.skip_binder())
1168         );
1169         err.span_label(span, found_str);
1170
1171         let found_span = found_span.unwrap_or(span);
1172         let expected_str = format!(
1173             "found signature of `{}`",
1174             build_fn_sig_string(self.tcx, expected_ref.skip_binder())
1175         );
1176         err.span_label(found_span, expected_str);
1177
1178         err
1179     }
1180 }
1181
1182 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1183     pub fn recursive_type_with_infinite_size_error(self,
1184                                                    type_def_id: DefId)
1185                                                    -> DiagnosticBuilder<'tcx>
1186     {
1187         assert!(type_def_id.is_local());
1188         let span = self.hir.span_if_local(type_def_id).unwrap();
1189         let span = self.sess.source_map().def_span(span);
1190         let mut err = struct_span_err!(self.sess, span, E0072,
1191                                        "recursive type `{}` has infinite size",
1192                                        self.item_path_str(type_def_id));
1193         err.span_label(span, "recursive type has infinite size");
1194         err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
1195                            at some point to make `{}` representable",
1196                           self.item_path_str(type_def_id)));
1197         err
1198     }
1199
1200     pub fn report_object_safety_error(self,
1201                                       span: Span,
1202                                       trait_def_id: DefId,
1203                                       violations: Vec<ObjectSafetyViolation>)
1204                                       -> DiagnosticBuilder<'tcx>
1205     {
1206         let trait_str = self.item_path_str(trait_def_id);
1207         let span = self.sess.source_map().def_span(span);
1208         let mut err = struct_span_err!(
1209             self.sess, span, E0038,
1210             "the trait `{}` cannot be made into an object",
1211             trait_str);
1212         err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
1213
1214         let mut reported_violations = FxHashSet();
1215         for violation in violations {
1216             if reported_violations.insert(violation.clone()) {
1217                 err.note(&violation.error_msg());
1218             }
1219         }
1220         err
1221     }
1222 }
1223
1224 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1225     fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
1226                               body_id: Option<hir::BodyId>) {
1227         // Unable to successfully determine, probably means
1228         // insufficient type information, but could mean
1229         // ambiguous impls. The latter *ought* to be a
1230         // coherence violation, so we don't report it here.
1231
1232         let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
1233         let span = obligation.cause.span;
1234
1235         debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
1236                predicate,
1237                obligation);
1238
1239         // Ambiguity errors are often caused as fallout from earlier
1240         // errors. So just ignore them if this infcx is tainted.
1241         if self.is_tainted_by_errors() {
1242             return;
1243         }
1244
1245         match predicate {
1246             ty::Predicate::Trait(ref data) => {
1247                 let trait_ref = data.to_poly_trait_ref();
1248                 let self_ty = trait_ref.self_ty();
1249                 if predicate.references_error() {
1250                     return;
1251                 }
1252                 // Typically, this ambiguity should only happen if
1253                 // there are unresolved type inference variables
1254                 // (otherwise it would suggest a coherence
1255                 // failure). But given #21974 that is not necessarily
1256                 // the case -- we can have multiple where clauses that
1257                 // are only distinguished by a region, which results
1258                 // in an ambiguity even when all types are fully
1259                 // known, since we don't dispatch based on region
1260                 // relationships.
1261
1262                 // This is kind of a hack: it frequently happens that some earlier
1263                 // error prevents types from being fully inferred, and then we get
1264                 // a bunch of uninteresting errors saying something like "<generic
1265                 // #0> doesn't implement Sized".  It may even be true that we
1266                 // could just skip over all checks where the self-ty is an
1267                 // inference variable, but I was afraid that there might be an
1268                 // inference variable created, registered as an obligation, and
1269                 // then never forced by writeback, and hence by skipping here we'd
1270                 // be ignoring the fact that we don't KNOW the type works
1271                 // out. Though even that would probably be harmless, given that
1272                 // we're only talking about builtin traits, which are known to be
1273                 // inhabited. But in any case I just threw in this check for
1274                 // has_errors() to be sure that compilation isn't happening
1275                 // anyway. In that case, why inundate the user.
1276                 if !self.tcx.sess.has_errors() {
1277                     if
1278                         self.tcx.lang_items().sized_trait()
1279                         .map_or(false, |sized_id| sized_id == trait_ref.def_id())
1280                     {
1281                         self.need_type_info_err(body_id, span, self_ty).emit();
1282                     } else {
1283                         let mut err = struct_span_err!(self.tcx.sess,
1284                                                        span, E0283,
1285                                                        "type annotations required: \
1286                                                         cannot resolve `{}`",
1287                                                        predicate);
1288                         self.note_obligation_cause(&mut err, obligation);
1289                         err.emit();
1290                     }
1291                 }
1292             }
1293
1294             ty::Predicate::WellFormed(ty) => {
1295                 // Same hacky approach as above to avoid deluging user
1296                 // with error messages.
1297                 if !ty.references_error() && !self.tcx.sess.has_errors() {
1298                     self.need_type_info_err(body_id, span, ty).emit();
1299                 }
1300             }
1301
1302             ty::Predicate::Subtype(ref data) => {
1303                 if data.references_error() || self.tcx.sess.has_errors() {
1304                     // no need to overload user in such cases
1305                 } else {
1306                     let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
1307                     // both must be type variables, or the other would've been instantiated
1308                     assert!(a.is_ty_var() && b.is_ty_var());
1309                     self.need_type_info_err(body_id,
1310                                             obligation.cause.span,
1311                                             a).emit();
1312                 }
1313             }
1314
1315             _ => {
1316                 if !self.tcx.sess.has_errors() {
1317                     let mut err = struct_span_err!(self.tcx.sess,
1318                                                    obligation.cause.span, E0284,
1319                                                    "type annotations required: \
1320                                                     cannot resolve `{}`",
1321                                                    predicate);
1322                     self.note_obligation_cause(&mut err, obligation);
1323                     err.emit();
1324                 }
1325             }
1326         }
1327     }
1328
1329     /// Returns whether the trait predicate may apply for *some* assignment
1330     /// to the type parameters.
1331     fn predicate_can_apply(&self,
1332                            param_env: ty::ParamEnv<'tcx>,
1333                            pred: ty::PolyTraitRef<'tcx>)
1334                            -> bool {
1335         struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
1336             infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
1337             var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>
1338         }
1339
1340         impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ParamToVarFolder<'a, 'gcx, 'tcx> {
1341             fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.infcx.tcx }
1342
1343             fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1344                 if let ty::Param(ty::ParamTy {name, ..}) = ty.sty {
1345                     let infcx = self.infcx;
1346                     self.var_map.entry(ty).or_insert_with(||
1347                         infcx.next_ty_var(
1348                             TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, name)))
1349                 } else {
1350                     ty.super_fold_with(self)
1351                 }
1352             }
1353         }
1354
1355         self.probe(|_| {
1356             let mut selcx = SelectionContext::new(self);
1357
1358             let cleaned_pred = pred.fold_with(&mut ParamToVarFolder {
1359                 infcx: self,
1360                 var_map: FxHashMap()
1361             });
1362
1363             let cleaned_pred = super::project::normalize(
1364                 &mut selcx,
1365                 param_env,
1366                 ObligationCause::dummy(),
1367                 &cleaned_pred
1368             ).value;
1369
1370             let obligation = Obligation::new(
1371                 ObligationCause::dummy(),
1372                 param_env,
1373                 cleaned_pred.to_predicate()
1374             );
1375
1376             self.predicate_may_hold(&obligation)
1377         })
1378     }
1379
1380     fn note_obligation_cause<T>(&self,
1381                                 err: &mut DiagnosticBuilder,
1382                                 obligation: &Obligation<'tcx, T>)
1383         where T: fmt::Display
1384     {
1385         self.note_obligation_cause_code(err,
1386                                         &obligation.predicate,
1387                                         &obligation.cause.code,
1388                                         &mut vec![]);
1389     }
1390
1391     fn note_obligation_cause_code<T>(&self,
1392                                      err: &mut DiagnosticBuilder,
1393                                      predicate: &T,
1394                                      cause_code: &ObligationCauseCode<'tcx>,
1395                                      obligated_types: &mut Vec<&ty::TyS<'tcx>>)
1396         where T: fmt::Display
1397     {
1398         let tcx = self.tcx;
1399         match *cause_code {
1400             ObligationCauseCode::ExprAssignable |
1401             ObligationCauseCode::MatchExpressionArm { .. } |
1402             ObligationCauseCode::IfExpression |
1403             ObligationCauseCode::IfExpressionWithNoElse |
1404             ObligationCauseCode::MainFunctionType |
1405             ObligationCauseCode::StartFunctionType |
1406             ObligationCauseCode::IntrinsicType |
1407             ObligationCauseCode::MethodReceiver |
1408             ObligationCauseCode::ReturnNoExpression |
1409             ObligationCauseCode::MiscObligation => {
1410             }
1411             ObligationCauseCode::SliceOrArrayElem => {
1412                 err.note("slice and array elements must have `Sized` type");
1413             }
1414             ObligationCauseCode::TupleElem => {
1415                 err.note("only the last element of a tuple may have a dynamically sized type");
1416             }
1417             ObligationCauseCode::ProjectionWf(data) => {
1418                 err.note(&format!("required so that the projection `{}` is well-formed",
1419                                   data));
1420             }
1421             ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
1422                 err.note(&format!("required so that reference `{}` does not outlive its referent",
1423                                   ref_ty));
1424             }
1425             ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
1426                 err.note(&format!("required so that the lifetime bound of `{}` for `{}` \
1427                                    is satisfied",
1428                                   region, object_ty));
1429             }
1430             ObligationCauseCode::ItemObligation(item_def_id) => {
1431                 let item_name = tcx.item_path_str(item_def_id);
1432                 let msg = format!("required by `{}`", item_name);
1433
1434                 if let Some(sp) = tcx.hir.span_if_local(item_def_id) {
1435                     let sp = tcx.sess.source_map().def_span(sp);
1436                     err.span_note(sp, &msg);
1437                 } else {
1438                     err.note(&msg);
1439                 }
1440             }
1441             ObligationCauseCode::ObjectCastObligation(object_ty) => {
1442                 err.note(&format!("required for the cast to the object type `{}`",
1443                                   self.ty_to_string(object_ty)));
1444             }
1445             ObligationCauseCode::RepeatVec => {
1446                 err.note("the `Copy` trait is required because the \
1447                           repeated element will be copied");
1448             }
1449             ObligationCauseCode::VariableType(_) => {
1450                 err.note("all local variables must have a statically known size");
1451                 if !self.tcx.features().unsized_locals {
1452                     err.help("unsized locals are gated as an unstable feature");
1453                 }
1454             }
1455             ObligationCauseCode::SizedArgumentType => {
1456                 err.note("all function arguments must have a statically known size");
1457                 if !self.tcx.features().unsized_locals {
1458                     err.help("unsized locals are gated as an unstable feature");
1459                 }
1460             }
1461             ObligationCauseCode::SizedReturnType => {
1462                 err.note("the return type of a function must have a \
1463                           statically known size");
1464             }
1465             ObligationCauseCode::SizedYieldType => {
1466                 err.note("the yield type of a generator must have a \
1467                           statically known size");
1468             }
1469             ObligationCauseCode::AssignmentLhsSized => {
1470                 err.note("the left-hand-side of an assignment must have a statically known size");
1471             }
1472             ObligationCauseCode::TupleInitializerSized => {
1473                 err.note("tuples must have a statically known size to be initialized");
1474             }
1475             ObligationCauseCode::StructInitializerSized => {
1476                 err.note("structs must have a statically known size to be initialized");
1477             }
1478             ObligationCauseCode::FieldSized { adt_kind: ref item, last } => {
1479                 match *item {
1480                     AdtKind::Struct => {
1481                         if last {
1482                             err.note("the last field of a packed struct may only have a \
1483                                       dynamically sized type if it does not need drop to be run");
1484                         } else {
1485                             err.note("only the last field of a struct may have a dynamically \
1486                                       sized type");
1487                         }
1488                     }
1489                     AdtKind::Union => {
1490                         err.note("no field of a union may have a dynamically sized type");
1491                     }
1492                     AdtKind::Enum => {
1493                         err.note("no field of an enum variant may have a dynamically sized type");
1494                     }
1495                 }
1496             }
1497             ObligationCauseCode::ConstSized => {
1498                 err.note("constant expressions must have a statically known size");
1499             }
1500             ObligationCauseCode::SharedStatic => {
1501                 err.note("shared static variables must have a type that implements `Sync`");
1502             }
1503             ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
1504                 let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1505                 let ty = parent_trait_ref.skip_binder().self_ty();
1506                 err.note(&format!("required because it appears within the type `{}`", ty));
1507                 obligated_types.push(ty);
1508
1509                 let parent_predicate = parent_trait_ref.to_predicate();
1510                 if !self.is_recursive_obligation(obligated_types, &data.parent_code) {
1511                     self.note_obligation_cause_code(err,
1512                                                     &parent_predicate,
1513                                                     &data.parent_code,
1514                                                     obligated_types);
1515                 }
1516             }
1517             ObligationCauseCode::ImplDerivedObligation(ref data) => {
1518                 let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1519                 err.note(
1520                     &format!("required because of the requirements on the impl of `{}` for `{}`",
1521                              parent_trait_ref,
1522                              parent_trait_ref.skip_binder().self_ty()));
1523                 let parent_predicate = parent_trait_ref.to_predicate();
1524                 self.note_obligation_cause_code(err,
1525                                                 &parent_predicate,
1526                                                 &data.parent_code,
1527                                                 obligated_types);
1528             }
1529             ObligationCauseCode::CompareImplMethodObligation { .. } => {
1530                 err.note(
1531                     &format!("the requirement `{}` appears on the impl method \
1532                               but not on the corresponding trait method",
1533                              predicate));
1534             }
1535             ObligationCauseCode::ReturnType(_) |
1536             ObligationCauseCode::BlockTailExpression(_) => (),
1537             ObligationCauseCode::TrivialBound => {
1538                 err.help("see issue #48214");
1539                 if tcx.sess.opts.unstable_features.is_nightly_build() {
1540                     err.help("add #![feature(trivial_bounds)] to the \
1541                               crate attributes to enable",
1542                     );
1543                 }
1544             }
1545         }
1546     }
1547
1548     fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder) {
1549         let current_limit = self.tcx.sess.recursion_limit.get();
1550         let suggested_limit = current_limit * 2;
1551         err.help(&format!("consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
1552                           suggested_limit));
1553     }
1554
1555     fn is_recursive_obligation(&self,
1556                                obligated_types: &mut Vec<&ty::TyS<'tcx>>,
1557                                cause_code: &ObligationCauseCode<'tcx>) -> bool {
1558         if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
1559             let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1560
1561             if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) {
1562                 return true;
1563             }
1564         }
1565         false
1566     }
1567 }
1568
1569 /// Summarizes information
1570 #[derive(Clone)]
1571 pub enum ArgKind {
1572     /// An argument of non-tuple type. Parameters are (name, ty)
1573     Arg(String, String),
1574
1575     /// An argument of tuple type. For a "found" argument, the span is
1576     /// the locationo in the source of the pattern. For a "expected"
1577     /// argument, it will be None. The vector is a list of (name, ty)
1578     /// strings for the components of the tuple.
1579     Tuple(Option<Span>, Vec<(String, String)>),
1580 }
1581
1582 impl ArgKind {
1583     fn empty() -> ArgKind {
1584         ArgKind::Arg("_".to_owned(), "_".to_owned())
1585     }
1586
1587     /// Creates an `ArgKind` from the expected type of an
1588     /// argument. It has no name (`_`) and an optional source span.
1589     pub fn from_expected_ty(t: Ty<'_>, span: Option<Span>) -> ArgKind {
1590         match t.sty {
1591             ty::Tuple(ref tys) => ArgKind::Tuple(
1592                 span,
1593                 tys.iter()
1594                    .map(|ty| ("_".to_owned(), ty.sty.to_string()))
1595                    .collect::<Vec<_>>()
1596             ),
1597             _ => ArgKind::Arg("_".to_owned(), t.sty.to_string()),
1598         }
1599     }
1600 }