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.
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.
14 MismatchedProjectionTypes,
18 OutputTypeParameterMismatch,
23 ObjectSafetyViolation,
25 object_safety_violations,
28 use fmt_macros::{Parser, Piece, Position};
29 use hir::def_id::DefId;
31 use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
33 use ty::fold::{TypeFoldable, TypeFolder};
34 use util::nodemap::{FnvHashMap, FnvHashSet};
38 use syntax::attr::{AttributeMethods, AttrMetaMethods};
39 use syntax::codemap::Span;
40 use syntax::errors::DiagnosticBuilder;
42 #[derive(Debug, PartialEq, Eq, Hash)]
43 pub struct TraitErrorKey<'tcx> {
45 predicate: ty::Predicate<'tcx>
48 impl<'tcx> TraitErrorKey<'tcx> {
49 fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
50 e: &FulfillmentError<'tcx>) -> Self {
52 infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
54 span: e.obligation.cause.span,
55 predicate: infcx.tcx.erase_regions(&predicate)
60 pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
61 errors: &Vec<FulfillmentError<'tcx>>) {
63 report_fulfillment_error(infcx, error);
67 fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
68 error: &FulfillmentError<'tcx>) {
69 let error_key = TraitErrorKey::from_error(infcx, error);
70 debug!("report_fulfillment_errors({:?}) - key={:?}",
72 if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
73 debug!("report_fulfillment_errors: skipping duplicate");
77 FulfillmentErrorCode::CodeSelectionError(ref e) => {
78 report_selection_error(infcx, &error.obligation, e);
80 FulfillmentErrorCode::CodeProjectionError(ref e) => {
81 report_projection_error(infcx, &error.obligation, e);
83 FulfillmentErrorCode::CodeAmbiguity => {
84 maybe_report_ambiguity(infcx, &error.obligation);
89 pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
90 obligation: &PredicateObligation<'tcx>,
91 error: &MismatchedProjectionTypes<'tcx>)
94 infcx.resolve_type_vars_if_possible(&obligation.predicate);
96 if !predicate.references_error() {
97 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0271,
98 "type mismatch resolving `{}`: {}",
101 note_obligation_cause(infcx, &mut err, obligation);
106 fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
107 trait_ref: ty::PolyTraitRef<'tcx>,
108 span: Span) -> Option<String> {
109 let trait_ref = trait_ref.skip_binder();
110 let def_id = trait_ref.def_id;
111 let mut report = None;
112 for item in infcx.tcx.get_attrs(def_id).iter() {
113 if item.check_name("rustc_on_unimplemented") {
114 let err_sp = item.meta().span.substitute_dummy(span);
115 let def = infcx.tcx.lookup_trait_def(def_id);
116 let trait_str = def.trait_ref.to_string();
117 if let Some(ref istring) = item.value_str() {
118 let mut generic_map = def.generics.types.iter_enumerated()
119 .map(|(param, i, gen)| {
120 (gen.name.as_str().to_string(),
121 trait_ref.substs.types.get(param, i)
123 }).collect::<FnvHashMap<String, String>>();
124 generic_map.insert("Self".to_string(),
125 trait_ref.self_ty().to_string());
126 let parser = Parser::new(&istring);
127 let mut errored = false;
128 let err: String = parser.filter_map(|p| {
130 Piece::String(s) => Some(s),
131 Piece::NextArgument(a) => match a.position {
132 Position::ArgumentNamed(s) => match generic_map.get(s) {
133 Some(val) => Some(val),
135 span_err!(infcx.tcx.sess, err_sp, E0272,
136 "the #[rustc_on_unimplemented] \
138 trait definition for {} refers to \
139 non-existent type parameter {}",
146 span_err!(infcx.tcx.sess, err_sp, E0273,
147 "the #[rustc_on_unimplemented] \
149 trait definition for {} must have named \
151 eg `#[rustc_on_unimplemented = \
160 // Report only if the format string checks out
165 span_err!(infcx.tcx.sess, err_sp, E0274,
166 "the #[rustc_on_unimplemented] attribute on \
167 trait definition for {} must have a value, \
168 eg `#[rustc_on_unimplemented = \"foo\"]`",
177 fn find_similar_impl_candidates<'a, 'tcx>(
178 infcx: &InferCtxt<'a, 'tcx>,
179 trait_ref: ty::PolyTraitRef<'tcx>)
180 -> Vec<ty::TraitRef<'tcx>>
182 let simp = fast_reject::simplify_type(infcx.tcx,
183 trait_ref.skip_binder().self_ty(),
185 let mut impl_candidates = Vec::new();
186 let trait_def = infcx.tcx.lookup_trait_def(trait_ref.def_id());
189 Some(simp) => trait_def.for_each_impl(infcx.tcx, |def_id| {
190 let imp = infcx.tcx.impl_trait_ref(def_id).unwrap();
191 let imp_simp = fast_reject::simplify_type(infcx.tcx,
194 if let Some(imp_simp) = imp_simp {
195 if simp != imp_simp {
199 impl_candidates.push(imp);
201 None => trait_def.for_each_impl(infcx.tcx, |def_id| {
202 impl_candidates.push(
203 infcx.tcx.impl_trait_ref(def_id).unwrap());
209 fn report_similar_impl_candidates(span: Span,
210 err: &mut DiagnosticBuilder,
211 impl_candidates: &[ty::TraitRef])
213 err.fileline_help(span, &format!("the following implementations were found:"));
215 let end = cmp::min(4, impl_candidates.len());
216 for candidate in &impl_candidates[0..end] {
217 err.fileline_help(span, &format!(" {:?}", candidate));
219 if impl_candidates.len() > 4 {
220 err.fileline_help(span, &format!("and {} others", impl_candidates.len()-4));
224 /// Reports that an overflow has occurred and halts compilation. We
225 /// halt compilation unconditionally because it is important that
226 /// overflows never be masked -- they basically represent computations
227 /// whose result could not be truly determined and thus we can't say
228 /// if the program type checks or not -- and they are unusual
229 /// occurrences in any case.
230 pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
231 obligation: &Obligation<'tcx, T>,
232 suggest_increasing_limit: bool)
234 where T: fmt::Display + TypeFoldable<'tcx>
237 infcx.resolve_type_vars_if_possible(&obligation.predicate);
238 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
239 "overflow evaluating the requirement `{}`",
242 if suggest_increasing_limit {
243 suggest_new_overflow_limit(infcx.tcx, &mut err, obligation.cause.span);
246 note_obligation_cause(infcx, &mut err, obligation);
249 infcx.tcx.sess.abort_if_errors();
253 /// Reports that a cycle was detected which led to overflow and halts
254 /// compilation. This is equivalent to `report_overflow_error` except
255 /// that we can give a more helpful error message (and, in particular,
256 /// we do not suggest increasing the overflow limit, which is not
258 pub fn report_overflow_error_cycle<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
259 cycle: &Vec<PredicateObligation<'tcx>>)
262 assert!(cycle.len() > 1);
264 debug!("report_overflow_error_cycle(cycle length = {})", cycle.len());
266 let cycle = infcx.resolve_type_vars_if_possible(cycle);
268 debug!("report_overflow_error_cycle: cycle={:?}", cycle);
270 assert_eq!(&cycle[0].predicate, &cycle.last().unwrap().predicate);
272 try_report_overflow_error_type_of_infinite_size(infcx, &cycle);
273 report_overflow_error(infcx, &cycle[0], false);
276 /// If a cycle results from evaluated whether something is Sized, that
277 /// is a particular special case that always results from a struct or
278 /// enum definition that lacks indirection (e.g., `struct Foo { x: Foo
279 /// }`). We wish to report a targeted error for this case.
280 pub fn try_report_overflow_error_type_of_infinite_size<'a, 'tcx>(
281 infcx: &InferCtxt<'a, 'tcx>,
282 cycle: &[PredicateObligation<'tcx>])
284 let sized_trait = match infcx.tcx.lang_items.sized_trait() {
289 match cycle[0].predicate {
290 ty::Predicate::Trait(ref data) => data.def_id() == sized_trait,
298 // The only way to have a type of infinite size is to have,
299 // somewhere, a struct/enum type involved. Identify all such types
300 // and report the cycle to the user.
302 let struct_enum_tys: Vec<_> =
304 .flat_map(|obligation| match obligation.predicate {
305 ty::Predicate::Trait(ref data) => {
306 assert_eq!(data.def_id(), sized_trait);
307 let self_ty = data.skip_binder().trait_ref.self_ty(); // (*)
308 // (*) ok to skip binder because this is just
309 // error reporting and regions don't really
312 ty::TyEnum(..) | ty::TyStruct(..) => Some(self_ty),
317 span_bug!(obligation.cause.span,
318 "Sized cycle involving non-trait-ref: {:?}",
319 obligation.predicate);
324 assert!(!struct_enum_tys.is_empty());
326 // This is a bit tricky. We want to pick a "main type" in the
327 // listing that is local to the current crate, so we can give a
328 // good span to the user. But it might not be the first one in our
329 // cycle list. So find the first one that is local and then
331 let (main_index, main_def_id) =
332 struct_enum_tys.iter()
334 .filter_map(|(index, ty)| match ty.sty {
335 ty::TyEnum(adt_def, _) | ty::TyStruct(adt_def, _)
336 if adt_def.did.is_local() =>
337 Some((index, adt_def.did)),
342 .unwrap(); // should always be SOME local type involved!
344 // Rotate so that the "main" type is at index 0.
345 let struct_enum_tys: Vec<_> =
346 struct_enum_tys.iter()
349 .chain(struct_enum_tys.iter().cloned().take(main_index))
353 let mut err = recursive_type_with_infinite_size_error(tcx, main_def_id);
354 let len = struct_enum_tys.len();
356 let span = tcx.map.span_if_local(main_def_id).unwrap();
357 err.fileline_note(span,
358 &format!("type `{}` is embedded within `{}`...",
360 struct_enum_tys[1]));
361 for &next_ty in &struct_enum_tys[1..len-1] {
362 err.fileline_note(span,
363 &format!("...which in turn is embedded within `{}`...", next_ty));
365 err.fileline_note(span,
366 &format!("...which in turn is embedded within `{}`, \
367 completing the cycle.",
368 struct_enum_tys[len-1]));
371 infcx.tcx.sess.abort_if_errors();
375 pub fn recursive_type_with_infinite_size_error<'tcx>(tcx: &TyCtxt<'tcx>,
377 -> DiagnosticBuilder<'tcx>
379 assert!(type_def_id.is_local());
380 let span = tcx.map.span_if_local(type_def_id).unwrap();
381 let mut err = struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size",
382 tcx.item_path_str(type_def_id));
383 err.fileline_help(span, &format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
384 at some point to make `{}` representable",
385 tcx.item_path_str(type_def_id)));
389 pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
390 obligation: &PredicateObligation<'tcx>,
391 error: &SelectionError<'tcx>)
394 SelectionError::Unimplemented => {
395 if let ObligationCauseCode::CompareImplMethodObligation = obligation.cause.code {
397 infcx.tcx.sess, obligation.cause.span, E0276,
398 "the requirement `{}` appears on the impl \
399 method but not on the corresponding trait method",
400 obligation.predicate);
402 match obligation.predicate {
403 ty::Predicate::Trait(ref trait_predicate) => {
404 let trait_predicate =
405 infcx.resolve_type_vars_if_possible(trait_predicate);
407 if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() {
408 let trait_ref = trait_predicate.to_poly_trait_ref();
409 let mut err = struct_span_err!(
410 infcx.tcx.sess, obligation.cause.span, E0277,
411 "the trait bound `{}` is not satisfied",
412 trait_ref.to_predicate());
414 // Try to report a help message
416 if !trait_ref.has_infer_types() &&
417 predicate_can_apply(infcx, trait_ref)
419 // If a where-clause may be useful, remind the
420 // user that they can add it.
422 // don't display an on-unimplemented note, as
423 // these notes will often be of the form
424 // "the type `T` can't be frobnicated"
425 // which is somewhat confusing.
426 err.fileline_help(obligation.cause.span, &format!(
427 "consider adding a `where {}` bound",
428 trait_ref.to_predicate()
430 } else if let Some(s) = on_unimplemented_note(infcx, trait_ref,
431 obligation.cause.span) {
432 // Otherwise, if there is an on-unimplemented note,
434 err.fileline_note(obligation.cause.span, &s);
436 // If we can't show anything useful, try to find
439 let impl_candidates =
440 find_similar_impl_candidates(infcx, trait_ref);
441 if impl_candidates.len() > 0 {
442 report_similar_impl_candidates(obligation.cause.span,
443 &mut err, &impl_candidates);
446 note_obligation_cause(infcx, &mut err, obligation);
450 ty::Predicate::Equate(ref predicate) => {
451 let predicate = infcx.resolve_type_vars_if_possible(predicate);
452 let err = infcx.equality_predicate(obligation.cause.span,
453 &predicate).err().unwrap();
454 let mut err = struct_span_err!(
455 infcx.tcx.sess, obligation.cause.span, E0278,
456 "the requirement `{}` is not satisfied (`{}`)",
459 note_obligation_cause(infcx, &mut err, obligation);
463 ty::Predicate::RegionOutlives(ref predicate) => {
464 let predicate = infcx.resolve_type_vars_if_possible(predicate);
465 let err = infcx.region_outlives_predicate(obligation.cause.span,
466 &predicate).err().unwrap();
467 let mut err = struct_span_err!(
468 infcx.tcx.sess, obligation.cause.span, E0279,
469 "the requirement `{}` is not satisfied (`{}`)",
472 note_obligation_cause(infcx, &mut err, obligation);
476 ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
478 infcx.resolve_type_vars_if_possible(&obligation.predicate);
479 let mut err = struct_span_err!(
480 infcx.tcx.sess, obligation.cause.span, E0280,
481 "the requirement `{}` is not satisfied",
483 note_obligation_cause(infcx, &mut err, obligation);
487 ty::Predicate::ObjectSafe(trait_def_id) => {
488 let violations = object_safety_violations(
489 infcx.tcx, trait_def_id);
490 let mut err = report_object_safety_error(infcx.tcx,
491 obligation.cause.span,
494 note_obligation_cause(infcx, &mut err, obligation);
498 ty::Predicate::ClosureKind(closure_def_id, kind) => {
499 let found_kind = infcx.closure_kind(closure_def_id).unwrap();
500 let closure_span = infcx.tcx.map.span_if_local(closure_def_id).unwrap();
501 let mut err = struct_span_err!(
502 infcx.tcx.sess, closure_span, E0524,
503 "expected a closure that implements the `{}` trait, but this closure \
504 only implements `{}`",
508 obligation.cause.span,
509 &format!("the requirement to implement `{}` derives from here", kind));
513 ty::Predicate::WellFormed(ty) => {
514 // WF predicates cannot themselves make
515 // errors. They can only block due to
516 // ambiguity; otherwise, they always
517 // degenerate into other obligations
520 obligation.cause.span,
521 "WF predicate not satisfied for {:?}",
528 OutputTypeParameterMismatch(ref expected_trait_ref, ref actual_trait_ref, ref e) => {
529 let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
530 let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
531 if !actual_trait_ref.self_ty().references_error() {
532 let mut err = struct_span_err!(
533 infcx.tcx.sess, obligation.cause.span, E0281,
534 "type mismatch: the type `{}` implements the trait `{}`, \
535 but the trait `{}` is required ({})",
536 expected_trait_ref.self_ty(),
540 note_obligation_cause(infcx, &mut err, obligation);
545 TraitNotObjectSafe(did) => {
546 let violations = object_safety_violations(infcx.tcx, did);
547 let mut err = report_object_safety_error(infcx.tcx, obligation.cause.span, did,
549 note_obligation_cause(infcx, &mut err, obligation);
555 pub fn report_object_safety_error<'tcx>(tcx: &TyCtxt<'tcx>,
558 violations: Vec<ObjectSafetyViolation>)
559 -> DiagnosticBuilder<'tcx>
561 let mut err = struct_span_err!(
562 tcx.sess, span, E0038,
563 "the trait `{}` cannot be made into an object",
564 tcx.item_path_str(trait_def_id));
566 let mut reported_violations = FnvHashSet();
567 for violation in violations {
568 if !reported_violations.insert(violation.clone()) {
572 ObjectSafetyViolation::SizedSelf => {
575 "the trait cannot require that `Self : Sized`");
578 ObjectSafetyViolation::SupertraitSelf => {
581 "the trait cannot use `Self` as a type parameter \
582 in the supertrait listing");
585 ObjectSafetyViolation::Method(method,
586 MethodViolationCode::StaticMethod) => {
589 &format!("method `{}` has no receiver",
593 ObjectSafetyViolation::Method(method,
594 MethodViolationCode::ReferencesSelf) => {
597 &format!("method `{}` references the `Self` type \
598 in its arguments or return type",
602 ObjectSafetyViolation::Method(method,
603 MethodViolationCode::Generic) => {
606 &format!("method `{}` has generic type parameters",
614 pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
615 obligation: &PredicateObligation<'tcx>) {
616 // Unable to successfully determine, probably means
617 // insufficient type information, but could mean
618 // ambiguous impls. The latter *ought* to be a
619 // coherence violation, so we don't report it here.
621 let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate);
623 debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
628 ty::Predicate::Trait(ref data) => {
629 let trait_ref = data.to_poly_trait_ref();
630 let self_ty = trait_ref.self_ty();
631 let all_types = &trait_ref.substs().types;
632 if all_types.references_error() {
634 // Typically, this ambiguity should only happen if
635 // there are unresolved type inference variables
636 // (otherwise it would suggest a coherence
637 // failure). But given #21974 that is not necessarily
638 // the case -- we can have multiple where clauses that
639 // are only distinguished by a region, which results
640 // in an ambiguity even when all types are fully
641 // known, since we don't dispatch based on region
644 // This is kind of a hack: it frequently happens that some earlier
645 // error prevents types from being fully inferred, and then we get
646 // a bunch of uninteresting errors saying something like "<generic
647 // #0> doesn't implement Sized". It may even be true that we
648 // could just skip over all checks where the self-ty is an
649 // inference variable, but I was afraid that there might be an
650 // inference variable created, registered as an obligation, and
651 // then never forced by writeback, and hence by skipping here we'd
652 // be ignoring the fact that we don't KNOW the type works
653 // out. Though even that would probably be harmless, given that
654 // we're only talking about builtin traits, which are known to be
655 // inhabited. But in any case I just threw in this check for
656 // has_errors() to be sure that compilation isn't happening
657 // anyway. In that case, why inundate the user.
658 if !infcx.tcx.sess.has_errors() {
660 infcx.tcx.lang_items.sized_trait()
661 .map_or(false, |sized_id| sized_id == trait_ref.def_id())
663 need_type_info(infcx, obligation.cause.span, self_ty);
665 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0283,
666 "type annotations required: \
667 cannot resolve `{}`",
669 note_obligation_cause(infcx, &mut err, obligation);
676 ty::Predicate::WellFormed(ty) => {
677 // Same hacky approach as above to avoid deluging user
678 // with error messages.
679 if !ty.references_error() && !infcx.tcx.sess.has_errors() {
680 need_type_info(infcx, obligation.cause.span, ty);
685 if !infcx.tcx.sess.has_errors() {
686 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0284,
687 "type annotations required: cannot resolve `{}`",
689 note_obligation_cause(infcx, &mut err, obligation);
696 /// Returns whether the trait predicate may apply for *some* assignment
697 /// to the type parameters.
698 fn predicate_can_apply<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
699 pred: ty::PolyTraitRef<'tcx>)
702 struct ParamToVarFolder<'a, 'tcx: 'a> {
703 infcx: &'a InferCtxt<'a, 'tcx>,
704 var_map: FnvHashMap<Ty<'tcx>, Ty<'tcx>>
707 impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx>
709 fn tcx(&self) -> &TyCtxt<'tcx> { self.infcx.tcx }
711 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
712 if let ty::TyParam(..) = ty.sty {
713 let infcx = self.infcx;
714 self.var_map.entry(ty).or_insert_with(|| infcx.next_ty_var())
716 ty.super_fold_with(self)
722 let mut selcx = SelectionContext::new(infcx);
724 let cleaned_pred = pred.fold_with(&mut ParamToVarFolder {
726 var_map: FnvHashMap()
729 let cleaned_pred = super::project::normalize(
731 ObligationCause::dummy(),
735 let obligation = Obligation::new(
736 ObligationCause::dummy(),
737 cleaned_pred.to_predicate()
740 selcx.evaluate_obligation(&obligation)
745 fn need_type_info<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
749 span_err!(infcx.tcx.sess, span, E0282,
750 "unable to infer enough type information about `{}`; \
751 type annotations or generic parameter binding required",
755 fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
756 err: &mut DiagnosticBuilder,
757 obligation: &Obligation<'tcx, T>)
758 where T: fmt::Display
760 note_obligation_cause_code(infcx,
762 &obligation.predicate,
763 obligation.cause.span,
764 &obligation.cause.code);
767 fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
768 err: &mut DiagnosticBuilder,
771 cause_code: &ObligationCauseCode<'tcx>)
772 where T: fmt::Display
776 ObligationCauseCode::MiscObligation => { }
777 ObligationCauseCode::SliceOrArrayElem => {
780 "slice and array elements must have `Sized` type");
782 ObligationCauseCode::ProjectionWf(data) => {
785 &format!("required so that the projection `{}` is well-formed",
788 ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
791 &format!("required so that reference `{}` does not outlive its referent",
794 ObligationCauseCode::ItemObligation(item_def_id) => {
795 let item_name = tcx.item_path_str(item_def_id);
798 &format!("required by `{}`", item_name));
800 ObligationCauseCode::ObjectCastObligation(object_ty) => {
804 "required for the cast to the object type `{}`",
805 infcx.ty_to_string(object_ty)));
807 ObligationCauseCode::RepeatVec => {
810 "the `Copy` trait is required because the \
811 repeated element will be copied");
813 ObligationCauseCode::VariableType(_) => {
816 "all local variables must have a statically known size");
818 ObligationCauseCode::ReturnType => {
821 "the return type of a function must have a \
822 statically known size");
824 ObligationCauseCode::AssignmentLhsSized => {
827 "the left-hand-side of an assignment must have a statically known size");
829 ObligationCauseCode::StructInitializerSized => {
832 "structs must have a statically known size to be initialized");
834 ObligationCauseCode::ClosureCapture(var_id, _, builtin_bound) => {
835 let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
836 let trait_name = tcx.item_path_str(def_id);
837 let name = tcx.local_var_name_str(var_id);
840 &format!("the closure that captures `{}` requires that all captured variables \
841 implement the trait `{}`",
845 ObligationCauseCode::FieldSized => {
848 "only the last field of a struct or enum variant \
849 may have a dynamically sized type");
851 ObligationCauseCode::SharedStatic => {
854 "shared static variables must have a type that implements `Sync`");
856 ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
857 let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
860 &format!("required because it appears within the type `{}`",
861 parent_trait_ref.0.self_ty()));
862 let parent_predicate = parent_trait_ref.to_predicate();
863 note_obligation_cause_code(infcx,
869 ObligationCauseCode::ImplDerivedObligation(ref data) => {
870 let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
873 &format!("required because of the requirements on the impl of `{}` for `{}`",
875 parent_trait_ref.0.self_ty()));
876 let parent_predicate = parent_trait_ref.to_predicate();
877 note_obligation_cause_code(infcx,
883 ObligationCauseCode::CompareImplMethodObligation => {
886 &format!("the requirement `{}` appears on the impl method \
887 but not on the corresponding trait method",
893 fn suggest_new_overflow_limit(tcx: &TyCtxt, err:&mut DiagnosticBuilder, span: Span) {
894 let current_limit = tcx.sess.recursion_limit.get();
895 let suggested_limit = current_limit * 2;
899 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",