]> git.proxmox.com Git - rustc.git/blame - src/librustc/middle/traits/error_reporting.rs
Imported Upstream version 1.7.0+dfsg1
[rustc.git] / src / librustc / middle / traits / error_reporting.rs
CommitLineData
1a4d82fc
JJ
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
11use super::{
12 FulfillmentError,
13 FulfillmentErrorCode,
14 MismatchedProjectionTypes,
c34b1796 15 Obligation,
1a4d82fc
JJ
16 ObligationCauseCode,
17 OutputTypeParameterMismatch,
d9579d0f 18 TraitNotObjectSafe,
1a4d82fc
JJ
19 PredicateObligation,
20 SelectionError,
d9579d0f
AL
21 ObjectSafetyViolation,
22 MethodViolationCode,
23 object_safety_violations,
1a4d82fc
JJ
24};
25
85aaf69f 26use fmt_macros::{Parser, Piece, Position};
e9174d1e 27use middle::def_id::DefId;
1a4d82fc 28use middle::infer::InferCtxt;
9cc50fc6
SL
29use middle::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, Ty, TypeFoldable};
30use middle::ty::fast_reject;
e9174d1e
SL
31use util::nodemap::{FnvHashMap, FnvHashSet};
32
9cc50fc6 33use std::cmp;
62682a34 34use std::fmt;
b039eaaf 35use syntax::attr::{AttributeMethods, AttrMetaMethods};
9cc50fc6
SL
36use syntax::codemap::Span;
37use syntax::errors::DiagnosticBuilder;
e9174d1e
SL
38
39#[derive(Debug, PartialEq, Eq, Hash)]
40pub struct TraitErrorKey<'tcx> {
e9174d1e
SL
41 span: Span,
42 predicate: ty::Predicate<'tcx>
43}
44
45impl<'tcx> TraitErrorKey<'tcx> {
46 fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
47 e: &FulfillmentError<'tcx>) -> Self {
48 let predicate =
49 infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
50 TraitErrorKey {
e9174d1e
SL
51 span: e.obligation.cause.span,
52 predicate: infcx.tcx.erase_regions(&predicate)
53 }
54 }
55}
1a4d82fc
JJ
56
57pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
58 errors: &Vec<FulfillmentError<'tcx>>) {
85aaf69f 59 for error in errors {
1a4d82fc
JJ
60 report_fulfillment_error(infcx, error);
61 }
62}
63
64fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
65 error: &FulfillmentError<'tcx>) {
e9174d1e
SL
66 let error_key = TraitErrorKey::from_error(infcx, error);
67 debug!("report_fulfillment_errors({:?}) - key={:?}",
68 error, error_key);
69 if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
70 debug!("report_fulfillment_errors: skipping duplicate");
71 return;
72 }
1a4d82fc
JJ
73 match error.code {
74 FulfillmentErrorCode::CodeSelectionError(ref e) => {
75 report_selection_error(infcx, &error.obligation, e);
76 }
77 FulfillmentErrorCode::CodeProjectionError(ref e) => {
78 report_projection_error(infcx, &error.obligation, e);
79 }
80 FulfillmentErrorCode::CodeAmbiguity => {
81 maybe_report_ambiguity(infcx, &error.obligation);
82 }
83 }
84}
85
86pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
87 obligation: &PredicateObligation<'tcx>,
88 error: &MismatchedProjectionTypes<'tcx>)
89{
90 let predicate =
91 infcx.resolve_type_vars_if_possible(&obligation.predicate);
e9174d1e 92
62682a34 93 // The TyError created by normalize_to_error can end up being unified
d9579d0f
AL
94 // into all obligations: for example, if our obligation is something
95 // like `$X = <() as Foo<$X>>::Out` and () does not implement Foo<_>,
62682a34 96 // then $X will be unified with TyError, but the error still needs to be
d9579d0f
AL
97 // reported.
98 if !infcx.tcx.sess.has_errors() || !predicate.references_error() {
9cc50fc6 99 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0271,
e9174d1e
SL
100 "type mismatch resolving `{}`: {}",
101 predicate,
102 error.err);
9cc50fc6
SL
103 note_obligation_cause(infcx, &mut err, obligation);
104 err.emit();
1a4d82fc
JJ
105 }
106}
107
85aaf69f
SL
108fn 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;
c1a9b12d 113 for item in infcx.tcx.get_attrs(def_id).iter() {
85aaf69f 114 if item.check_name("rustc_on_unimplemented") {
e9174d1e 115 let err_sp = item.meta().span.substitute_dummy(span);
c1a9b12d 116 let def = infcx.tcx.lookup_trait_def(def_id);
62682a34 117 let trait_str = def.trait_ref.to_string();
85aaf69f
SL
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)
62682a34 123 .to_string())
e9174d1e 124 }).collect::<FnvHashMap<String, String>>();
85aaf69f 125 generic_map.insert("Self".to_string(),
62682a34 126 trait_ref.self_ty().to_string());
85aaf69f
SL
127 let parser = Parser::new(&istring);
128 let mut errored = false;
129 let err: String = parser.filter_map(|p| {
130 match 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),
135 None => {
136 span_err!(infcx.tcx.sess, err_sp, E0272,
137 "the #[rustc_on_unimplemented] \
138 attribute on \
139 trait definition for {} refers to \
140 non-existent type parameter {}",
141 trait_str, s);
142 errored = true;
143 None
144 }
145 },
146 _ => {
147 span_err!(infcx.tcx.sess, err_sp, E0273,
148 "the #[rustc_on_unimplemented] \
149 attribute on \
150 trait definition for {} must have named \
151 format arguments, \
152 eg `#[rustc_on_unimplemented = \
153 \"foo {{T}}\"]`",
154 trait_str);
155 errored = true;
156 None
157 }
158 }
159 }
160 }).collect();
161 // Report only if the format string checks out
162 if !errored {
163 report = Some(err);
164 }
165 } else {
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\"]`",
170 trait_str);
171 }
172 break;
173 }
174 }
175 report
176}
177
c34b1796
AL
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.
184pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
185 obligation: &Obligation<'tcx, T>)
186 -> !
9cc50fc6 187 where T: fmt::Display + TypeFoldable<'tcx>
c34b1796
AL
188{
189 let predicate =
190 infcx.resolve_type_vars_if_possible(&obligation.predicate);
9cc50fc6
SL
191 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
192 "overflow evaluating the requirement `{}`",
193 predicate);
c34b1796 194
9cc50fc6 195 suggest_new_overflow_limit(infcx.tcx, &mut err, obligation.cause.span);
c34b1796 196
9cc50fc6 197 note_obligation_cause(infcx, &mut err, obligation);
c34b1796 198
9cc50fc6 199 err.emit();
c34b1796
AL
200 infcx.tcx.sess.abort_if_errors();
201 unreachable!();
202}
203
1a4d82fc
JJ
204pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
205 obligation: &PredicateObligation<'tcx>,
206 error: &SelectionError<'tcx>)
207{
208 match *error {
1a4d82fc 209 SelectionError::Unimplemented => {
e9174d1e 210 if let ObligationCauseCode::CompareImplMethodObligation = obligation.cause.code {
9cc50fc6
SL
211 span_err!(
212 infcx.tcx.sess, obligation.cause.span, E0276,
e9174d1e
SL
213 "the requirement `{}` appears on the impl \
214 method but not on the corresponding trait method",
b039eaaf 215 obligation.predicate);
e9174d1e
SL
216 } else {
217 match obligation.predicate {
218 ty::Predicate::Trait(ref trait_predicate) => {
219 let trait_predicate =
220 infcx.resolve_type_vars_if_possible(trait_predicate);
221
222 if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() {
223 let trait_ref = trait_predicate.to_poly_trait_ref();
9cc50fc6
SL
224 let mut err = struct_span_err!(
225 infcx.tcx.sess, obligation.cause.span, E0277,
e9174d1e
SL
226 "the trait `{}` is not implemented for the type `{}`",
227 trait_ref, trait_ref.self_ty());
228
229 // Check if it has a custom "#[rustc_on_unimplemented]"
230 // error message, report with that message if it does
231 let custom_note = report_on_unimplemented(infcx, &trait_ref.0,
232 obligation.cause.span);
233 if let Some(s) = custom_note {
9cc50fc6
SL
234 err.fileline_note(obligation.cause.span, &s);
235 } else {
236 let simp = fast_reject::simplify_type(infcx.tcx,
237 trait_ref.self_ty(),
238 true);
239 let mut impl_candidates = Vec::new();
240 let trait_def = infcx.tcx.lookup_trait_def(trait_ref.def_id());
241
242 match simp {
243 Some(simp) => trait_def.for_each_impl(infcx.tcx, |def_id| {
244 let imp = infcx.tcx.impl_trait_ref(def_id).unwrap();
245 let imp_simp = fast_reject::simplify_type(infcx.tcx,
246 imp.self_ty(),
247 true);
248 if let Some(imp_simp) = imp_simp {
249 if simp != imp_simp {
250 return;
251 }
252 }
253 impl_candidates.push(imp);
254 }),
255 None => trait_def.for_each_impl(infcx.tcx, |def_id| {
256 impl_candidates.push(
257 infcx.tcx.impl_trait_ref(def_id).unwrap());
258 })
259 };
260
261 if impl_candidates.len() > 0 {
262 err.fileline_help(
263 obligation.cause.span,
264 &format!("the following implementations were found:"));
265
266 let end = cmp::min(4, impl_candidates.len());
267 for candidate in &impl_candidates[0..end] {
268 err.fileline_help(obligation.cause.span,
269 &format!(" {:?}", candidate));
270 }
271 if impl_candidates.len() > 4 {
272 err.fileline_help(obligation.cause.span,
273 &format!("and {} others",
274 impl_candidates.len()-4));
275 }
276 }
85aaf69f 277 }
9cc50fc6
SL
278 note_obligation_cause(infcx, &mut err, obligation);
279 err.emit();
85aaf69f 280 }
9cc50fc6 281 },
e9174d1e
SL
282 ty::Predicate::Equate(ref predicate) => {
283 let predicate = infcx.resolve_type_vars_if_possible(predicate);
284 let err = infcx.equality_predicate(obligation.cause.span,
285 &predicate).err().unwrap();
9cc50fc6
SL
286 let mut err = struct_span_err!(
287 infcx.tcx.sess, obligation.cause.span, E0278,
e9174d1e
SL
288 "the requirement `{}` is not satisfied (`{}`)",
289 predicate,
290 err);
9cc50fc6
SL
291 note_obligation_cause(infcx, &mut err, obligation);
292 err.emit();
e9174d1e 293 }
85aaf69f 294
e9174d1e
SL
295 ty::Predicate::RegionOutlives(ref predicate) => {
296 let predicate = infcx.resolve_type_vars_if_possible(predicate);
297 let err = infcx.region_outlives_predicate(obligation.cause.span,
298 &predicate).err().unwrap();
9cc50fc6
SL
299 let mut err = struct_span_err!(
300 infcx.tcx.sess, obligation.cause.span, E0279,
e9174d1e
SL
301 "the requirement `{}` is not satisfied (`{}`)",
302 predicate,
303 err);
9cc50fc6
SL
304 note_obligation_cause(infcx, &mut err, obligation);
305 err.emit();
e9174d1e 306 }
1a4d82fc 307
e9174d1e
SL
308 ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
309 let predicate =
310 infcx.resolve_type_vars_if_possible(&obligation.predicate);
9cc50fc6
SL
311 let mut err = struct_span_err!(
312 infcx.tcx.sess, obligation.cause.span, E0280,
e9174d1e
SL
313 "the requirement `{}` is not satisfied",
314 predicate);
9cc50fc6
SL
315 note_obligation_cause(infcx, &mut err, obligation);
316 err.emit();
e9174d1e
SL
317 }
318
319 ty::Predicate::ObjectSafe(trait_def_id) => {
b039eaaf
SL
320 let violations = object_safety_violations(
321 infcx.tcx, trait_def_id);
9cc50fc6
SL
322 let mut err = report_object_safety_error(infcx.tcx,
323 obligation.cause.span,
324 trait_def_id,
325 violations);
326 note_obligation_cause(infcx, &mut err, obligation);
327 err.emit();
e9174d1e
SL
328 }
329
330 ty::Predicate::WellFormed(ty) => {
331 // WF predicates cannot themselves make
332 // errors. They can only block due to
333 // ambiguity; otherwise, they always
334 // degenerate into other obligations
335 // (which may fail).
336 infcx.tcx.sess.span_bug(
337 obligation.cause.span,
338 &format!("WF predicate not satisfied for {:?}", ty));
85aaf69f 339 }
1a4d82fc
JJ
340 }
341 }
342 }
85aaf69f 343
1a4d82fc
JJ
344 OutputTypeParameterMismatch(ref expected_trait_ref, ref actual_trait_ref, ref e) => {
345 let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
346 let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
c1a9b12d 347 if !actual_trait_ref.self_ty().references_error() {
9cc50fc6
SL
348 let mut err = struct_span_err!(
349 infcx.tcx.sess, obligation.cause.span, E0281,
e9174d1e
SL
350 "type mismatch: the type `{}` implements the trait `{}`, \
351 but the trait `{}` is required ({})",
352 expected_trait_ref.self_ty(),
353 expected_trait_ref,
354 actual_trait_ref,
355 e);
9cc50fc6
SL
356 note_obligation_cause(infcx, &mut err, obligation);
357 err.emit();
1a4d82fc
JJ
358 }
359 }
d9579d0f
AL
360
361 TraitNotObjectSafe(did) => {
b039eaaf 362 let violations = object_safety_violations(infcx.tcx, did);
9cc50fc6
SL
363 let mut err = report_object_safety_error(infcx.tcx, obligation.cause.span, did,
364 violations);
365 note_obligation_cause(infcx, &mut err, obligation);
366 err.emit();
e9174d1e
SL
367 }
368 }
369}
d9579d0f 370
e9174d1e
SL
371pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
372 span: Span,
373 trait_def_id: DefId,
9cc50fc6
SL
374 violations: Vec<ObjectSafetyViolation>)
375 -> DiagnosticBuilder<'tcx>
e9174d1e 376{
9cc50fc6
SL
377 let mut err = struct_span_err!(
378 tcx.sess, span, E0038,
e9174d1e
SL
379 "the trait `{}` cannot be made into an object",
380 tcx.item_path_str(trait_def_id));
d9579d0f 381
e9174d1e 382 let mut reported_violations = FnvHashSet();
b039eaaf 383 for violation in violations {
e9174d1e
SL
384 if !reported_violations.insert(violation.clone()) {
385 continue;
386 }
387 match violation {
388 ObjectSafetyViolation::SizedSelf => {
9cc50fc6 389 err.fileline_note(
e9174d1e
SL
390 span,
391 "the trait cannot require that `Self : Sized`");
392 }
d9579d0f 393
e9174d1e 394 ObjectSafetyViolation::SupertraitSelf => {
9cc50fc6 395 err.fileline_note(
e9174d1e
SL
396 span,
397 "the trait cannot use `Self` as a type parameter \
398 in the supertrait listing");
399 }
d9579d0f 400
e9174d1e
SL
401 ObjectSafetyViolation::Method(method,
402 MethodViolationCode::StaticMethod) => {
9cc50fc6 403 err.fileline_note(
e9174d1e
SL
404 span,
405 &format!("method `{}` has no receiver",
406 method.name));
407 }
408
409 ObjectSafetyViolation::Method(method,
410 MethodViolationCode::ReferencesSelf) => {
9cc50fc6 411 err.fileline_note(
e9174d1e
SL
412 span,
413 &format!("method `{}` references the `Self` type \
414 in its arguments or return type",
415 method.name));
416 }
417
418 ObjectSafetyViolation::Method(method,
419 MethodViolationCode::Generic) => {
9cc50fc6 420 err.fileline_note(
e9174d1e
SL
421 span,
422 &format!("method `{}` has generic type parameters",
423 method.name));
d9579d0f
AL
424 }
425 }
1a4d82fc 426 }
9cc50fc6 427 err
1a4d82fc
JJ
428}
429
430pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
431 obligation: &PredicateObligation<'tcx>) {
432 // Unable to successfully determine, probably means
433 // insufficient type information, but could mean
434 // ambiguous impls. The latter *ought* to be a
435 // coherence violation, so we don't report it here.
436
437 let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate);
438
62682a34
SL
439 debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
440 predicate,
441 obligation);
1a4d82fc
JJ
442
443 match predicate {
444 ty::Predicate::Trait(ref data) => {
445 let trait_ref = data.to_poly_trait_ref();
446 let self_ty = trait_ref.self_ty();
447 let all_types = &trait_ref.substs().types;
c1a9b12d 448 if all_types.references_error() {
9cc50fc6
SL
449 } else {
450 // Typically, this ambiguity should only happen if
451 // there are unresolved type inference variables
452 // (otherwise it would suggest a coherence
453 // failure). But given #21974 that is not necessarily
454 // the case -- we can have multiple where clauses that
455 // are only distinguished by a region, which results
456 // in an ambiguity even when all types are fully
457 // known, since we don't dispatch based on region
458 // relationships.
459
1a4d82fc
JJ
460 // This is kind of a hack: it frequently happens that some earlier
461 // error prevents types from being fully inferred, and then we get
462 // a bunch of uninteresting errors saying something like "<generic
463 // #0> doesn't implement Sized". It may even be true that we
464 // could just skip over all checks where the self-ty is an
465 // inference variable, but I was afraid that there might be an
466 // inference variable created, registered as an obligation, and
467 // then never forced by writeback, and hence by skipping here we'd
468 // be ignoring the fact that we don't KNOW the type works
469 // out. Though even that would probably be harmless, given that
470 // we're only talking about builtin traits, which are known to be
471 // inhabited. But in any case I just threw in this check for
472 // has_errors() to be sure that compilation isn't happening
473 // anyway. In that case, why inundate the user.
474 if !infcx.tcx.sess.has_errors() {
475 if
476 infcx.tcx.lang_items.sized_trait()
477 .map_or(false, |sized_id| sized_id == trait_ref.def_id())
478 {
e9174d1e 479 need_type_info(infcx, obligation.cause.span, self_ty);
1a4d82fc 480 } else {
9cc50fc6
SL
481 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0283,
482 "type annotations required: \
483 cannot resolve `{}`",
484 predicate);
485 note_obligation_cause(infcx, &mut err, obligation);
486 err.emit();
1a4d82fc
JJ
487 }
488 }
1a4d82fc
JJ
489 }
490 }
491
e9174d1e
SL
492 ty::Predicate::WellFormed(ty) => {
493 // Same hacky approach as above to avoid deluging user
494 // with error messages.
495 if !ty.references_error() && !infcx.tcx.sess.has_errors() {
496 need_type_info(infcx, obligation.cause.span, ty);
497 }
498 }
499
1a4d82fc
JJ
500 _ => {
501 if !infcx.tcx.sess.has_errors() {
9cc50fc6
SL
502 let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0284,
503 "type annotations required: cannot resolve `{}`",
504 predicate);
505 note_obligation_cause(infcx, &mut err, obligation);
506 err.emit();
1a4d82fc
JJ
507 }
508 }
509 }
510}
511
e9174d1e
SL
512fn need_type_info<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
513 span: Span,
514 ty: Ty<'tcx>)
515{
516 span_err!(infcx.tcx.sess, span, E0282,
517 "unable to infer enough type information about `{}`; \
518 type annotations or generic parameter binding required",
519 ty);
520}
521
c34b1796 522fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
9cc50fc6 523 err: &mut DiagnosticBuilder,
c34b1796 524 obligation: &Obligation<'tcx, T>)
62682a34 525 where T: fmt::Display
1a4d82fc
JJ
526{
527 note_obligation_cause_code(infcx,
9cc50fc6 528 err,
1a4d82fc
JJ
529 &obligation.predicate,
530 obligation.cause.span,
531 &obligation.cause.code);
532}
533
c34b1796 534fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
9cc50fc6 535 err: &mut DiagnosticBuilder,
c34b1796
AL
536 predicate: &T,
537 cause_span: Span,
538 cause_code: &ObligationCauseCode<'tcx>)
62682a34 539 where T: fmt::Display
1a4d82fc
JJ
540{
541 let tcx = infcx.tcx;
542 match *cause_code {
543 ObligationCauseCode::MiscObligation => { }
e9174d1e 544 ObligationCauseCode::SliceOrArrayElem => {
9cc50fc6 545 err.fileline_note(
e9174d1e 546 cause_span,
92a42be0 547 "slice and array elements must have `Sized` type");
e9174d1e
SL
548 }
549 ObligationCauseCode::ProjectionWf(data) => {
9cc50fc6 550 err.fileline_note(
e9174d1e
SL
551 cause_span,
552 &format!("required so that the projection `{}` is well-formed",
553 data));
554 }
555 ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
9cc50fc6 556 err.fileline_note(
e9174d1e
SL
557 cause_span,
558 &format!("required so that reference `{}` does not outlive its referent",
559 ref_ty));
560 }
1a4d82fc 561 ObligationCauseCode::ItemObligation(item_def_id) => {
c1a9b12d 562 let item_name = tcx.item_path_str(item_def_id);
9cc50fc6 563 err.fileline_note(
1a4d82fc 564 cause_span,
85aaf69f 565 &format!("required by `{}`", item_name));
1a4d82fc
JJ
566 }
567 ObligationCauseCode::ObjectCastObligation(object_ty) => {
9cc50fc6 568 err.fileline_note(
1a4d82fc 569 cause_span,
85aaf69f 570 &format!(
1a4d82fc 571 "required for the cast to the object type `{}`",
85aaf69f 572 infcx.ty_to_string(object_ty)));
1a4d82fc
JJ
573 }
574 ObligationCauseCode::RepeatVec => {
9cc50fc6 575 err.fileline_note(
1a4d82fc
JJ
576 cause_span,
577 "the `Copy` trait is required because the \
578 repeated element will be copied");
579 }
580 ObligationCauseCode::VariableType(_) => {
9cc50fc6 581 err.fileline_note(
1a4d82fc
JJ
582 cause_span,
583 "all local variables must have a statically known size");
584 }
585 ObligationCauseCode::ReturnType => {
9cc50fc6 586 err.fileline_note(
1a4d82fc
JJ
587 cause_span,
588 "the return type of a function must have a \
589 statically known size");
590 }
591 ObligationCauseCode::AssignmentLhsSized => {
9cc50fc6 592 err.fileline_note(
1a4d82fc
JJ
593 cause_span,
594 "the left-hand-side of an assignment must have a statically known size");
595 }
596 ObligationCauseCode::StructInitializerSized => {
9cc50fc6 597 err.fileline_note(
1a4d82fc
JJ
598 cause_span,
599 "structs must have a statically known size to be initialized");
600 }
e9174d1e 601 ObligationCauseCode::ClosureCapture(var_id, _, builtin_bound) => {
1a4d82fc 602 let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
c1a9b12d
SL
603 let trait_name = tcx.item_path_str(def_id);
604 let name = tcx.local_var_name_str(var_id);
9cc50fc6 605 err.fileline_note(
e9174d1e
SL
606 cause_span,
607 &format!("the closure that captures `{}` requires that all captured variables \
608 implement the trait `{}`",
609 name,
610 trait_name));
1a4d82fc
JJ
611 }
612 ObligationCauseCode::FieldSized => {
9cc50fc6 613 err.fileline_note(
e9174d1e
SL
614 cause_span,
615 "only the last field of a struct or enum variant \
616 may have a dynamically sized type");
1a4d82fc 617 }
1a4d82fc 618 ObligationCauseCode::SharedStatic => {
9cc50fc6 619 err.fileline_note(
e9174d1e
SL
620 cause_span,
621 "shared static variables must have a type that implements `Sync`");
1a4d82fc
JJ
622 }
623 ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
624 let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
9cc50fc6 625 err.fileline_note(
e9174d1e
SL
626 cause_span,
627 &format!("required because it appears within the type `{}`",
628 parent_trait_ref.0.self_ty()));
c1a9b12d 629 let parent_predicate = parent_trait_ref.to_predicate();
9cc50fc6
SL
630 note_obligation_cause_code(infcx,
631 err,
632 &parent_predicate,
633 cause_span,
634 &*data.parent_code);
1a4d82fc
JJ
635 }
636 ObligationCauseCode::ImplDerivedObligation(ref data) => {
637 let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
9cc50fc6 638 err.fileline_note(
e9174d1e
SL
639 cause_span,
640 &format!("required because of the requirements on the impl of `{}` for `{}`",
641 parent_trait_ref,
642 parent_trait_ref.0.self_ty()));
c1a9b12d 643 let parent_predicate = parent_trait_ref.to_predicate();
9cc50fc6
SL
644 note_obligation_cause_code(infcx,
645 err,
646 &parent_predicate,
647 cause_span,
648 &*data.parent_code);
1a4d82fc 649 }
85aaf69f 650 ObligationCauseCode::CompareImplMethodObligation => {
9cc50fc6 651 err.fileline_note(
e9174d1e
SL
652 cause_span,
653 &format!("the requirement `{}` appears on the impl method \
654 but not on the corresponding trait method",
655 predicate));
85aaf69f 656 }
1a4d82fc
JJ
657 }
658}
659
9cc50fc6 660fn suggest_new_overflow_limit(tcx: &ty::ctxt, err:&mut DiagnosticBuilder, span: Span) {
1a4d82fc
JJ
661 let current_limit = tcx.sess.recursion_limit.get();
662 let suggested_limit = current_limit * 2;
9cc50fc6 663 err.fileline_note(
1a4d82fc
JJ
664 span,
665 &format!(
666 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
c34b1796 667 suggested_limit));
1a4d82fc 668}