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
,
17 OutputTypeParameterMismatch
,
21 ObjectSafetyViolation
,
23 object_safety_violations
,
26 use fmt_macros
::{Parser, Piece, Position}
;
27 use middle
::def_id
::DefId
;
28 use middle
::infer
::InferCtxt
;
29 use middle
::ty
::{self, ToPredicate, ToPolyTraitRef, TraitRef, Ty, TypeFoldable}
;
30 use middle
::ty
::fast_reject
;
31 use util
::nodemap
::{FnvHashMap, FnvHashSet}
;
35 use syntax
::attr
::{AttributeMethods, AttrMetaMethods}
;
36 use syntax
::codemap
::Span
;
37 use syntax
::errors
::DiagnosticBuilder
;
39 #[derive(Debug, PartialEq, Eq, Hash)]
40 pub struct TraitErrorKey
<'tcx
> {
42 predicate
: ty
::Predicate
<'tcx
>
45 impl<'tcx
> TraitErrorKey
<'tcx
> {
46 fn from_error
<'a
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
47 e
: &FulfillmentError
<'tcx
>) -> Self {
49 infcx
.resolve_type_vars_if_possible(&e
.obligation
.predicate
);
51 span
: e
.obligation
.cause
.span
,
52 predicate
: infcx
.tcx
.erase_regions(&predicate
)
57 pub fn report_fulfillment_errors
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
58 errors
: &Vec
<FulfillmentError
<'tcx
>>) {
60 report_fulfillment_error(infcx
, error
);
64 fn report_fulfillment_error
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
65 error
: &FulfillmentError
<'tcx
>) {
66 let error_key
= TraitErrorKey
::from_error(infcx
, error
);
67 debug
!("report_fulfillment_errors({:?}) - key={:?}",
69 if !infcx
.reported_trait_errors
.borrow_mut().insert(error_key
) {
70 debug
!("report_fulfillment_errors: skipping duplicate");
74 FulfillmentErrorCode
::CodeSelectionError(ref e
) => {
75 report_selection_error(infcx
, &error
.obligation
, e
);
77 FulfillmentErrorCode
::CodeProjectionError(ref e
) => {
78 report_projection_error(infcx
, &error
.obligation
, e
);
80 FulfillmentErrorCode
::CodeAmbiguity
=> {
81 maybe_report_ambiguity(infcx
, &error
.obligation
);
86 pub fn report_projection_error
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
87 obligation
: &PredicateObligation
<'tcx
>,
88 error
: &MismatchedProjectionTypes
<'tcx
>)
91 infcx
.resolve_type_vars_if_possible(&obligation
.predicate
);
93 // The TyError created by normalize_to_error can end up being unified
94 // into all obligations: for example, if our obligation is something
95 // like `$X = <() as Foo<$X>>::Out` and () does not implement Foo<_>,
96 // then $X will be unified with TyError, but the error still needs to be
98 if !infcx
.tcx
.sess
.has_errors() || !predicate
.references_error() {
99 let mut err
= struct_span_err
!(infcx
.tcx
.sess
, obligation
.cause
.span
, E0271
,
100 "type mismatch resolving `{}`: {}",
103 note_obligation_cause(infcx
, &mut err
, obligation
);
108 fn report_on_unimplemented
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
109 trait_ref
: &TraitRef
<'tcx
>,
110 span
: Span
) -> Option
<String
> {
111 let def_id
= trait_ref
.def_id
;
112 let mut report
= None
;
113 for item
in infcx
.tcx
.get_attrs(def_id
).iter() {
114 if item
.check_name("rustc_on_unimplemented") {
115 let err_sp
= item
.meta().span
.substitute_dummy(span
);
116 let def
= infcx
.tcx
.lookup_trait_def(def_id
);
117 let trait_str
= def
.trait_ref
.to_string();
118 if let Some(ref istring
) = item
.value_str() {
119 let mut generic_map
= def
.generics
.types
.iter_enumerated()
120 .map(|(param
, i
, gen
)| {
121 (gen
.name
.as_str().to_string(),
122 trait_ref
.substs
.types
.get(param
, i
)
124 }).collect
::<FnvHashMap
<String
, String
>>();
125 generic_map
.insert("Self".to_string(),
126 trait_ref
.self_ty().to_string());
127 let parser
= Parser
::new(&istring
);
128 let mut errored
= false;
129 let err
: String
= parser
.filter_map(|p
| {
131 Piece
::String(s
) => Some(s
),
132 Piece
::NextArgument(a
) => match a
.position
{
133 Position
::ArgumentNamed(s
) => match generic_map
.get(s
) {
134 Some(val
) => Some(val
),
136 span_err
!(infcx
.tcx
.sess
, err_sp
, E0272
,
137 "the #[rustc_on_unimplemented] \
139 trait definition for {} refers to \
140 non-existent type parameter {}",
147 span_err
!(infcx
.tcx
.sess
, err_sp
, E0273
,
148 "the #[rustc_on_unimplemented] \
150 trait definition for {} must have named \
152 eg `#[rustc_on_unimplemented = \
161 // Report only if the format string checks out
166 span_err
!(infcx
.tcx
.sess
, err_sp
, E0274
,
167 "the #[rustc_on_unimplemented] attribute on \
168 trait definition for {} must have a value, \
169 eg `#[rustc_on_unimplemented = \"foo\"]`",
178 /// Reports that an overflow has occurred and halts compilation. We
179 /// halt compilation unconditionally because it is important that
180 /// overflows never be masked -- they basically represent computations
181 /// whose result could not be truly determined and thus we can't say
182 /// if the program type checks or not -- and they are unusual
183 /// occurrences in any case.
184 pub fn report_overflow_error
<'a
, 'tcx
, T
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
185 obligation
: &Obligation
<'tcx
, T
>,
186 suggest_increasing_limit
: bool
)
188 where T
: fmt
::Display
+ TypeFoldable
<'tcx
>
191 infcx
.resolve_type_vars_if_possible(&obligation
.predicate
);
192 let mut err
= struct_span_err
!(infcx
.tcx
.sess
, obligation
.cause
.span
, E0275
,
193 "overflow evaluating the requirement `{}`",
196 if suggest_increasing_limit
{
197 suggest_new_overflow_limit(infcx
.tcx
, &mut err
, obligation
.cause
.span
);
200 note_obligation_cause(infcx
, &mut err
, obligation
);
203 infcx
.tcx
.sess
.abort_if_errors();
207 /// Reports that a cycle was detected which led to overflow and halts
208 /// compilation. This is equivalent to `report_overflow_error` except
209 /// that we can give a more helpful error message (and, in particular,
210 /// we do not suggest increasing the overflow limit, which is not
212 pub fn report_overflow_error_cycle
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
213 cycle
: &Vec
<PredicateObligation
<'tcx
>>)
216 assert
!(cycle
.len() > 1);
218 debug
!("report_overflow_error_cycle(cycle length = {})", cycle
.len());
220 let cycle
= infcx
.resolve_type_vars_if_possible(cycle
);
222 debug
!("report_overflow_error_cycle: cycle={:?}", cycle
);
224 assert_eq
!(&cycle
[0].predicate
, &cycle
.last().unwrap().predicate
);
226 try_report_overflow_error_type_of_infinite_size(infcx
, &cycle
);
227 report_overflow_error(infcx
, &cycle
[0], false);
230 /// If a cycle results from evaluated whether something is Sized, that
231 /// is a particular special case that always results from a struct or
232 /// enum definition that lacks indirection (e.g., `struct Foo { x: Foo
233 /// }`). We wish to report a targeted error for this case.
234 pub fn try_report_overflow_error_type_of_infinite_size
<'a
, 'tcx
>(
235 infcx
: &InferCtxt
<'a
, 'tcx
>,
236 cycle
: &[PredicateObligation
<'tcx
>])
238 let sized_trait
= match infcx
.tcx
.lang_items
.sized_trait() {
243 match cycle
[0].predicate
{
244 ty
::Predicate
::Trait(ref data
) => data
.def_id() == sized_trait
,
252 // The only way to have a type of infinite size is to have,
253 // somewhere, a struct/enum type involved. Identify all such types
254 // and report the cycle to the user.
256 let struct_enum_tys
: Vec
<_
> =
258 .flat_map(|obligation
| match obligation
.predicate
{
259 ty
::Predicate
::Trait(ref data
) => {
260 assert_eq
!(data
.def_id(), sized_trait
);
261 let self_ty
= data
.skip_binder().trait_ref
.self_ty(); // (*)
262 // (*) ok to skip binder because this is just
263 // error reporting and regions don't really
266 ty
::TyEnum(..) | ty
::TyStruct(..) => Some(self_ty
),
271 infcx
.tcx
.sess
.span_bug(obligation
.cause
.span
,
272 &format
!("Sized cycle involving non-trait-ref: {:?}",
273 obligation
.predicate
));
278 assert
!(!struct_enum_tys
.is_empty());
280 // This is a bit tricky. We want to pick a "main type" in the
281 // listing that is local to the current crate, so we can give a
282 // good span to the user. But it might not be the first one in our
283 // cycle list. So find the first one that is local and then
285 let (main_index
, main_def_id
) =
286 struct_enum_tys
.iter()
288 .filter_map(|(index
, ty
)| match ty
.sty
{
289 ty
::TyEnum(adt_def
, _
) | ty
::TyStruct(adt_def
, _
)
290 if adt_def
.did
.is_local() =>
291 Some((index
, adt_def
.did
)),
296 .unwrap(); // should always be SOME local type involved!
298 // Rotate so that the "main" type is at index 0.
299 let struct_enum_tys
: Vec
<_
> =
300 struct_enum_tys
.iter()
303 .chain(struct_enum_tys
.iter().cloned().take(main_index
))
307 let mut err
= recursive_type_with_infinite_size_error(tcx
, main_def_id
);
308 let len
= struct_enum_tys
.len();
310 let span
= tcx
.map
.span_if_local(main_def_id
).unwrap();
311 err
.fileline_note(span
,
312 &format
!("type `{}` is embedded within `{}`...",
314 struct_enum_tys
[1]));
315 for &next_ty
in &struct_enum_tys
[1..len
-1] {
316 err
.fileline_note(span
,
317 &format
!("...which in turn is embedded within `{}`...", next_ty
));
319 err
.fileline_note(span
,
320 &format
!("...which in turn is embedded within `{}`, \
321 completing the cycle.",
322 struct_enum_tys
[len
-1]));
325 infcx
.tcx
.sess
.abort_if_errors();
329 pub fn recursive_type_with_infinite_size_error
<'tcx
>(tcx
: &ty
::ctxt
<'tcx
>,
331 -> DiagnosticBuilder
<'tcx
>
333 assert
!(type_def_id
.is_local());
334 let span
= tcx
.map
.span_if_local(type_def_id
).unwrap();
335 let mut err
= struct_span_err
!(tcx
.sess
, span
, E0072
, "recursive type `{}` has infinite size",
336 tcx
.item_path_str(type_def_id
));
337 err
.fileline_help(span
, &format
!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
338 at some point to make `{}` representable",
339 tcx
.item_path_str(type_def_id
)));
343 pub fn report_selection_error
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
344 obligation
: &PredicateObligation
<'tcx
>,
345 error
: &SelectionError
<'tcx
>)
348 SelectionError
::Unimplemented
=> {
349 if let ObligationCauseCode
::CompareImplMethodObligation
= obligation
.cause
.code
{
351 infcx
.tcx
.sess
, obligation
.cause
.span
, E0276
,
352 "the requirement `{}` appears on the impl \
353 method but not on the corresponding trait method",
354 obligation
.predicate
);
356 match obligation
.predicate
{
357 ty
::Predicate
::Trait(ref trait_predicate
) => {
358 let trait_predicate
=
359 infcx
.resolve_type_vars_if_possible(trait_predicate
);
361 if !infcx
.tcx
.sess
.has_errors() || !trait_predicate
.references_error() {
362 let trait_ref
= trait_predicate
.to_poly_trait_ref();
363 let mut err
= struct_span_err
!(
364 infcx
.tcx
.sess
, obligation
.cause
.span
, E0277
,
365 "the trait `{}` is not implemented for the type `{}`",
366 trait_ref
, trait_ref
.self_ty());
368 // Check if it has a custom "#[rustc_on_unimplemented]"
369 // error message, report with that message if it does
370 let custom_note
= report_on_unimplemented(infcx
, &trait_ref
.0,
371 obligation
.cause
.span
);
372 if let Some(s
) = custom_note
{
373 err
.fileline_note(obligation
.cause
.span
, &s
);
375 let simp
= fast_reject
::simplify_type(infcx
.tcx
,
378 let mut impl_candidates
= Vec
::new();
379 let trait_def
= infcx
.tcx
.lookup_trait_def(trait_ref
.def_id());
382 Some(simp
) => trait_def
.for_each_impl(infcx
.tcx
, |def_id
| {
383 let imp
= infcx
.tcx
.impl_trait_ref(def_id
).unwrap();
384 let imp_simp
= fast_reject
::simplify_type(infcx
.tcx
,
387 if let Some(imp_simp
) = imp_simp
{
388 if simp
!= imp_simp
{
392 impl_candidates
.push(imp
);
394 None
=> trait_def
.for_each_impl(infcx
.tcx
, |def_id
| {
395 impl_candidates
.push(
396 infcx
.tcx
.impl_trait_ref(def_id
).unwrap());
400 if impl_candidates
.len() > 0 {
402 obligation
.cause
.span
,
403 &format
!("the following implementations were found:"));
405 let end
= cmp
::min(4, impl_candidates
.len());
406 for candidate
in &impl_candidates
[0..end
] {
407 err
.fileline_help(obligation
.cause
.span
,
408 &format
!(" {:?}", candidate
));
410 if impl_candidates
.len() > 4 {
411 err
.fileline_help(obligation
.cause
.span
,
412 &format
!("and {} others",
413 impl_candidates
.len()-4));
417 note_obligation_cause(infcx
, &mut err
, obligation
);
421 ty
::Predicate
::Equate(ref predicate
) => {
422 let predicate
= infcx
.resolve_type_vars_if_possible(predicate
);
423 let err
= infcx
.equality_predicate(obligation
.cause
.span
,
424 &predicate
).err().unwrap();
425 let mut err
= struct_span_err
!(
426 infcx
.tcx
.sess
, obligation
.cause
.span
, E0278
,
427 "the requirement `{}` is not satisfied (`{}`)",
430 note_obligation_cause(infcx
, &mut err
, obligation
);
434 ty
::Predicate
::RegionOutlives(ref predicate
) => {
435 let predicate
= infcx
.resolve_type_vars_if_possible(predicate
);
436 let err
= infcx
.region_outlives_predicate(obligation
.cause
.span
,
437 &predicate
).err().unwrap();
438 let mut err
= struct_span_err
!(
439 infcx
.tcx
.sess
, obligation
.cause
.span
, E0279
,
440 "the requirement `{}` is not satisfied (`{}`)",
443 note_obligation_cause(infcx
, &mut err
, obligation
);
447 ty
::Predicate
::Projection(..) | ty
::Predicate
::TypeOutlives(..) => {
449 infcx
.resolve_type_vars_if_possible(&obligation
.predicate
);
450 let mut err
= struct_span_err
!(
451 infcx
.tcx
.sess
, obligation
.cause
.span
, E0280
,
452 "the requirement `{}` is not satisfied",
454 note_obligation_cause(infcx
, &mut err
, obligation
);
458 ty
::Predicate
::ObjectSafe(trait_def_id
) => {
459 let violations
= object_safety_violations(
460 infcx
.tcx
, trait_def_id
);
461 let mut err
= report_object_safety_error(infcx
.tcx
,
462 obligation
.cause
.span
,
465 note_obligation_cause(infcx
, &mut err
, obligation
);
469 ty
::Predicate
::WellFormed(ty
) => {
470 // WF predicates cannot themselves make
471 // errors. They can only block due to
472 // ambiguity; otherwise, they always
473 // degenerate into other obligations
475 infcx
.tcx
.sess
.span_bug(
476 obligation
.cause
.span
,
477 &format
!("WF predicate not satisfied for {:?}", ty
));
483 OutputTypeParameterMismatch(ref expected_trait_ref
, ref actual_trait_ref
, ref e
) => {
484 let expected_trait_ref
= infcx
.resolve_type_vars_if_possible(&*expected_trait_ref
);
485 let actual_trait_ref
= infcx
.resolve_type_vars_if_possible(&*actual_trait_ref
);
486 if !actual_trait_ref
.self_ty().references_error() {
487 let mut err
= struct_span_err
!(
488 infcx
.tcx
.sess
, obligation
.cause
.span
, E0281
,
489 "type mismatch: the type `{}` implements the trait `{}`, \
490 but the trait `{}` is required ({})",
491 expected_trait_ref
.self_ty(),
495 note_obligation_cause(infcx
, &mut err
, obligation
);
500 TraitNotObjectSafe(did
) => {
501 let violations
= object_safety_violations(infcx
.tcx
, did
);
502 let mut err
= report_object_safety_error(infcx
.tcx
, obligation
.cause
.span
, did
,
504 note_obligation_cause(infcx
, &mut err
, obligation
);
510 pub fn report_object_safety_error
<'tcx
>(tcx
: &ty
::ctxt
<'tcx
>,
513 violations
: Vec
<ObjectSafetyViolation
>)
514 -> DiagnosticBuilder
<'tcx
>
516 let mut err
= struct_span_err
!(
517 tcx
.sess
, span
, E0038
,
518 "the trait `{}` cannot be made into an object",
519 tcx
.item_path_str(trait_def_id
));
521 let mut reported_violations
= FnvHashSet();
522 for violation
in violations
{
523 if !reported_violations
.insert(violation
.clone()) {
527 ObjectSafetyViolation
::SizedSelf
=> {
530 "the trait cannot require that `Self : Sized`");
533 ObjectSafetyViolation
::SupertraitSelf
=> {
536 "the trait cannot use `Self` as a type parameter \
537 in the supertrait listing");
540 ObjectSafetyViolation
::Method(method
,
541 MethodViolationCode
::StaticMethod
) => {
544 &format
!("method `{}` has no receiver",
548 ObjectSafetyViolation
::Method(method
,
549 MethodViolationCode
::ReferencesSelf
) => {
552 &format
!("method `{}` references the `Self` type \
553 in its arguments or return type",
557 ObjectSafetyViolation
::Method(method
,
558 MethodViolationCode
::Generic
) => {
561 &format
!("method `{}` has generic type parameters",
569 pub fn maybe_report_ambiguity
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
570 obligation
: &PredicateObligation
<'tcx
>) {
571 // Unable to successfully determine, probably means
572 // insufficient type information, but could mean
573 // ambiguous impls. The latter *ought* to be a
574 // coherence violation, so we don't report it here.
576 let predicate
= infcx
.resolve_type_vars_if_possible(&obligation
.predicate
);
578 debug
!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
583 ty
::Predicate
::Trait(ref data
) => {
584 let trait_ref
= data
.to_poly_trait_ref();
585 let self_ty
= trait_ref
.self_ty();
586 let all_types
= &trait_ref
.substs().types
;
587 if all_types
.references_error() {
589 // Typically, this ambiguity should only happen if
590 // there are unresolved type inference variables
591 // (otherwise it would suggest a coherence
592 // failure). But given #21974 that is not necessarily
593 // the case -- we can have multiple where clauses that
594 // are only distinguished by a region, which results
595 // in an ambiguity even when all types are fully
596 // known, since we don't dispatch based on region
599 // This is kind of a hack: it frequently happens that some earlier
600 // error prevents types from being fully inferred, and then we get
601 // a bunch of uninteresting errors saying something like "<generic
602 // #0> doesn't implement Sized". It may even be true that we
603 // could just skip over all checks where the self-ty is an
604 // inference variable, but I was afraid that there might be an
605 // inference variable created, registered as an obligation, and
606 // then never forced by writeback, and hence by skipping here we'd
607 // be ignoring the fact that we don't KNOW the type works
608 // out. Though even that would probably be harmless, given that
609 // we're only talking about builtin traits, which are known to be
610 // inhabited. But in any case I just threw in this check for
611 // has_errors() to be sure that compilation isn't happening
612 // anyway. In that case, why inundate the user.
613 if !infcx
.tcx
.sess
.has_errors() {
615 infcx
.tcx
.lang_items
.sized_trait()
616 .map_or(false, |sized_id
| sized_id
== trait_ref
.def_id())
618 need_type_info(infcx
, obligation
.cause
.span
, self_ty
);
620 let mut err
= struct_span_err
!(infcx
.tcx
.sess
, obligation
.cause
.span
, E0283
,
621 "type annotations required: \
622 cannot resolve `{}`",
624 note_obligation_cause(infcx
, &mut err
, obligation
);
631 ty
::Predicate
::WellFormed(ty
) => {
632 // Same hacky approach as above to avoid deluging user
633 // with error messages.
634 if !ty
.references_error() && !infcx
.tcx
.sess
.has_errors() {
635 need_type_info(infcx
, obligation
.cause
.span
, ty
);
640 if !infcx
.tcx
.sess
.has_errors() {
641 let mut err
= struct_span_err
!(infcx
.tcx
.sess
, obligation
.cause
.span
, E0284
,
642 "type annotations required: cannot resolve `{}`",
644 note_obligation_cause(infcx
, &mut err
, obligation
);
651 fn need_type_info
<'a
, 'tcx
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
655 span_err
!(infcx
.tcx
.sess
, span
, E0282
,
656 "unable to infer enough type information about `{}`; \
657 type annotations or generic parameter binding required",
661 fn note_obligation_cause
<'a
, 'tcx
, T
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
662 err
: &mut DiagnosticBuilder
,
663 obligation
: &Obligation
<'tcx
, T
>)
664 where T
: fmt
::Display
666 note_obligation_cause_code(infcx
,
668 &obligation
.predicate
,
669 obligation
.cause
.span
,
670 &obligation
.cause
.code
);
673 fn note_obligation_cause_code
<'a
, 'tcx
, T
>(infcx
: &InferCtxt
<'a
, 'tcx
>,
674 err
: &mut DiagnosticBuilder
,
677 cause_code
: &ObligationCauseCode
<'tcx
>)
678 where T
: fmt
::Display
682 ObligationCauseCode
::MiscObligation
=> { }
683 ObligationCauseCode
::SliceOrArrayElem
=> {
686 "slice and array elements must have `Sized` type");
688 ObligationCauseCode
::ProjectionWf(data
) => {
691 &format
!("required so that the projection `{}` is well-formed",
694 ObligationCauseCode
::ReferenceOutlivesReferent(ref_ty
) => {
697 &format
!("required so that reference `{}` does not outlive its referent",
700 ObligationCauseCode
::ItemObligation(item_def_id
) => {
701 let item_name
= tcx
.item_path_str(item_def_id
);
704 &format
!("required by `{}`", item_name
));
706 ObligationCauseCode
::ObjectCastObligation(object_ty
) => {
710 "required for the cast to the object type `{}`",
711 infcx
.ty_to_string(object_ty
)));
713 ObligationCauseCode
::RepeatVec
=> {
716 "the `Copy` trait is required because the \
717 repeated element will be copied");
719 ObligationCauseCode
::VariableType(_
) => {
722 "all local variables must have a statically known size");
724 ObligationCauseCode
::ReturnType
=> {
727 "the return type of a function must have a \
728 statically known size");
730 ObligationCauseCode
::AssignmentLhsSized
=> {
733 "the left-hand-side of an assignment must have a statically known size");
735 ObligationCauseCode
::StructInitializerSized
=> {
738 "structs must have a statically known size to be initialized");
740 ObligationCauseCode
::ClosureCapture(var_id
, _
, builtin_bound
) => {
741 let def_id
= tcx
.lang_items
.from_builtin_kind(builtin_bound
).unwrap();
742 let trait_name
= tcx
.item_path_str(def_id
);
743 let name
= tcx
.local_var_name_str(var_id
);
746 &format
!("the closure that captures `{}` requires that all captured variables \
747 implement the trait `{}`",
751 ObligationCauseCode
::FieldSized
=> {
754 "only the last field of a struct or enum variant \
755 may have a dynamically sized type");
757 ObligationCauseCode
::SharedStatic
=> {
760 "shared static variables must have a type that implements `Sync`");
762 ObligationCauseCode
::BuiltinDerivedObligation(ref data
) => {
763 let parent_trait_ref
= infcx
.resolve_type_vars_if_possible(&data
.parent_trait_ref
);
766 &format
!("required because it appears within the type `{}`",
767 parent_trait_ref
.0.self_ty()));
768 let parent_predicate
= parent_trait_ref
.to_predicate();
769 note_obligation_cause_code(infcx
,
775 ObligationCauseCode
::ImplDerivedObligation(ref data
) => {
776 let parent_trait_ref
= infcx
.resolve_type_vars_if_possible(&data
.parent_trait_ref
);
779 &format
!("required because of the requirements on the impl of `{}` for `{}`",
781 parent_trait_ref
.0.self_ty()));
782 let parent_predicate
= parent_trait_ref
.to_predicate();
783 note_obligation_cause_code(infcx
,
789 ObligationCauseCode
::CompareImplMethodObligation
=> {
792 &format
!("the requirement `{}` appears on the impl method \
793 but not on the corresponding trait method",
799 fn suggest_new_overflow_limit(tcx
: &ty
::ctxt
, err
:&mut DiagnosticBuilder
, span
: Span
) {
800 let current_limit
= tcx
.sess
.recursion_limit
.get();
801 let suggested_limit
= current_limit
* 2;
805 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",