]> git.proxmox.com Git - rustc.git/blame - src/librustc/traits/error_reporting.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / librustc / 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,
54a0048b 16 ObligationCause,
1a4d82fc 17 ObligationCauseCode,
ea8adc8c
XL
18 OnUnimplementedDirective,
19 OnUnimplementedNote,
1a4d82fc 20 OutputTypeParameterMismatch,
d9579d0f 21 TraitNotObjectSafe,
ea8adc8c 22 ConstEvalFailure,
1a4d82fc 23 PredicateObligation,
041b39d2 24 Reveal,
54a0048b 25 SelectionContext,
1a4d82fc 26 SelectionError,
d9579d0f 27 ObjectSafetyViolation,
1a4d82fc
JJ
28};
29
8bb4bdeb 30use errors::DiagnosticBuilder;
041b39d2 31use hir;
54a0048b 32use hir::def_id::DefId;
476ff2be
SL
33use infer::{self, InferCtxt};
34use infer::type_variable::TypeVariableOrigin;
ea8adc8c 35use middle::const_val;
c30ab7b3 36use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
8bb4bdeb 37use std::fmt;
041b39d2
XL
38use syntax::ast;
39use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
ea8adc8c 40use ty::error::ExpectedFound;
54a0048b 41use ty::fast_reject;
a7813a04 42use ty::fold::TypeFolder;
9e0c209e 43use ty::subst::Subst;
cc61c64b 44use ty::SubtypePredicate;
476ff2be 45use util::nodemap::{FxHashMap, FxHashSet};
e9174d1e 46
476ff2be 47use syntax_pos::{DUMMY_SP, Span};
8bb4bdeb 48
041b39d2
XL
49impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
50 pub fn report_fulfillment_errors(&self,
51 errors: &Vec<FulfillmentError<'tcx>>,
52 body_id: Option<hir::BodyId>) {
53 #[derive(Debug)]
54 struct ErrorDescriptor<'tcx> {
55 predicate: ty::Predicate<'tcx>,
56 index: Option<usize>, // None if this is an old error
57 }
e9174d1e 58
041b39d2
XL
59 let mut error_map : FxHashMap<_, _> =
60 self.reported_trait_errors.borrow().iter().map(|(&span, predicates)| {
61 (span, predicates.iter().map(|predicate| ErrorDescriptor {
62 predicate: predicate.clone(),
63 index: None
64 }).collect())
65 }).collect();
66
67 for (index, error) in errors.iter().enumerate() {
68 error_map.entry(error.obligation.cause.span).or_insert(Vec::new()).push(
69 ErrorDescriptor {
70 predicate: error.obligation.predicate.clone(),
71 index: Some(index)
72 });
e9174d1e 73
041b39d2
XL
74 self.reported_trait_errors.borrow_mut()
75 .entry(error.obligation.cause.span).or_insert(Vec::new())
76 .push(error.obligation.predicate.clone());
e9174d1e 77 }
1a4d82fc 78
041b39d2
XL
79 // We do this in 2 passes because we want to display errors in order, tho
80 // maybe it *is* better to sort errors by span or something.
81 let mut is_suppressed: Vec<bool> = errors.iter().map(|_| false).collect();
82 for (_, error_set) in error_map.iter() {
83 // We want to suppress "duplicate" errors with the same span.
84 for error in error_set {
85 if let Some(index) = error.index {
86 // Suppress errors that are either:
87 // 1) strictly implied by another error.
88 // 2) implied by an error with a smaller index.
89 for error2 in error_set {
90 if error2.index.map_or(false, |index2| is_suppressed[index2]) {
91 // Avoid errors being suppressed by already-suppressed
92 // errors, to prevent all errors from being suppressed
93 // at once.
94 continue
95 }
8bb4bdeb 96
041b39d2
XL
97 if self.error_implies(&error2.predicate, &error.predicate) &&
98 !(error2.index >= error.index &&
99 self.error_implies(&error.predicate, &error2.predicate))
100 {
101 info!("skipping {:?} (implied by {:?})", error, error2);
102 is_suppressed[index] = true;
103 break
cc61c64b 104 }
cc61c64b 105 }
041b39d2 106 }
cc61c64b 107 }
cc61c64b 108 }
8bb4bdeb 109
041b39d2
XL
110 for (error, suppressed) in errors.iter().zip(is_suppressed) {
111 if !suppressed {
112 self.report_fulfillment_error(error, body_id);
113 }
114 }
cc61c64b 115 }
8bb4bdeb 116
3b2f2976
XL
117 // returns if `cond` not occurring implies that `error` does not occur - i.e. that
118 // `error` occurring implies that `cond` occurs.
041b39d2
XL
119 fn error_implies(&self,
120 cond: &ty::Predicate<'tcx>,
121 error: &ty::Predicate<'tcx>)
122 -> bool
123 {
124 if cond == error {
125 return true
8bb4bdeb 126 }
cc61c64b 127
041b39d2
XL
128 let (cond, error) = match (cond, error) {
129 (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error))
130 => (cond, error),
131 _ => {
132 // FIXME: make this work in other cases too.
133 return false
cc61c64b 134 }
041b39d2 135 };
8bb4bdeb 136
041b39d2
XL
137 for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) {
138 if let ty::Predicate::Trait(implication) = implication {
139 let error = error.to_poly_trait_ref();
140 let implication = implication.to_poly_trait_ref();
141 // FIXME: I'm just not taking associated types at all here.
142 // Eventually I'll need to implement param-env-aware
143 // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
144 let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
145 if let Ok(_) = self.can_sub(param_env, error, implication) {
146 debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
147 return true
148 }
149 }
a7813a04 150 }
041b39d2
XL
151
152 false
e9174d1e 153 }
a7813a04 154
041b39d2
XL
155 fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
156 body_id: Option<hir::BodyId>) {
157 debug!("report_fulfillment_errors({:?})", error);
a7813a04
XL
158 match error.code {
159 FulfillmentErrorCode::CodeSelectionError(ref e) => {
9e0c209e 160 self.report_selection_error(&error.obligation, e);
a7813a04
XL
161 }
162 FulfillmentErrorCode::CodeProjectionError(ref e) => {
9e0c209e 163 self.report_projection_error(&error.obligation, e);
a7813a04
XL
164 }
165 FulfillmentErrorCode::CodeAmbiguity => {
041b39d2 166 self.maybe_report_ambiguity(&error.obligation, body_id);
a7813a04 167 }
cc61c64b
XL
168 FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
169 self.report_mismatched_types(&error.obligation.cause,
170 expected_found.expected,
171 expected_found.found,
172 err.clone())
173 .emit();
174 }
1a4d82fc 175 }
a7813a04
XL
176 }
177
178 fn report_projection_error(&self,
179 obligation: &PredicateObligation<'tcx>,
9e0c209e 180 error: &MismatchedProjectionTypes<'tcx>)
a7813a04
XL
181 {
182 let predicate =
183 self.resolve_type_vars_if_possible(&obligation.predicate);
184
5bcae85e
SL
185 if predicate.references_error() {
186 return
187 }
9e0c209e 188
5bcae85e 189 self.probe(|_| {
5bcae85e
SL
190 let err_buf;
191 let mut err = &error.err;
192 let mut values = None;
193
194 // try to find the mismatched types to report the error with.
195 //
196 // this can fail if the problem was higher-ranked, in which
197 // cause I have no idea for a good error message.
198 if let ty::Predicate::Projection(ref data) = predicate {
199 let mut selcx = SelectionContext::new(self);
200 let (data, _) = self.replace_late_bound_regions_with_fresh_var(
a7813a04 201 obligation.cause.span,
5bcae85e
SL
202 infer::LateBoundRegionConversionTime::HigherRankedType,
203 data);
204 let normalized = super::normalize_projection_type(
205 &mut selcx,
7cac9316 206 obligation.param_env,
5bcae85e
SL
207 data.projection_ty,
208 obligation.cause.clone(),
209 0
210 );
7cac9316
XL
211 if let Err(error) = self.at(&obligation.cause, obligation.param_env)
212 .eq(normalized.value, data.ty) {
5bcae85e
SL
213 values = Some(infer::ValuePairs::Types(ExpectedFound {
214 expected: normalized.value,
215 found: data.ty,
216 }));
217 err_buf = error;
218 err = &err_buf;
219 }
a7813a04 220 }
5bcae85e
SL
221
222 let mut diag = struct_span_err!(
476ff2be 223 self.tcx.sess, obligation.cause.span, E0271,
5bcae85e
SL
224 "type mismatch resolving `{}`", predicate
225 );
476ff2be 226 self.note_type_err(&mut diag, &obligation.cause, None, values, err);
5bcae85e
SL
227 self.note_obligation_cause(&mut diag, obligation);
228 diag.emit();
229 });
a7813a04
XL
230 }
231
a7813a04
XL
232 fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
233 /// returns the fuzzy category of a given type, or None
234 /// if the type can be equated to any type.
235 fn type_category<'tcx>(t: Ty<'tcx>) -> Option<u32> {
236 match t.sty {
237 ty::TyBool => Some(0),
238 ty::TyChar => Some(1),
239 ty::TyStr => Some(2),
9e0c209e 240 ty::TyInt(..) | ty::TyUint(..) | ty::TyInfer(ty::IntVar(..)) => Some(3),
a7813a04 241 ty::TyFloat(..) | ty::TyInfer(ty::FloatVar(..)) => Some(4),
32a655c1 242 ty::TyRef(..) | ty::TyRawPtr(..) => Some(5),
9e0c209e
SL
243 ty::TyArray(..) | ty::TySlice(..) => Some(6),
244 ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(7),
476ff2be 245 ty::TyDynamic(..) => Some(8),
9e0c209e
SL
246 ty::TyClosure(..) => Some(9),
247 ty::TyTuple(..) => Some(10),
248 ty::TyProjection(..) => Some(11),
249 ty::TyParam(..) => Some(12),
250 ty::TyAnon(..) => Some(13),
251 ty::TyNever => Some(14),
252 ty::TyAdt(adt, ..) => match adt.adt_kind() {
253 AdtKind::Struct => Some(15),
254 AdtKind::Union => Some(16),
255 AdtKind::Enum => Some(17),
256 },
ea8adc8c 257 ty::TyGenerator(..) => Some(18),
a7813a04
XL
258 ty::TyInfer(..) | ty::TyError => None
259 }
260 }
261
262 match (type_category(a), type_category(b)) {
263 (Some(cat_a), Some(cat_b)) => match (&a.sty, &b.sty) {
9e0c209e 264 (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => def_a == def_b,
a7813a04
XL
265 _ => cat_a == cat_b
266 },
267 // infer and error can be equated to all types
268 _ => true
1a4d82fc
JJ
269 }
270 }
1a4d82fc 271
a7813a04
XL
272 fn impl_similar_to(&self,
273 trait_ref: ty::PolyTraitRef<'tcx>,
274 obligation: &PredicateObligation<'tcx>)
275 -> Option<DefId>
276 {
277 let tcx = self.tcx;
7cac9316 278 let param_env = obligation.param_env;
a7813a04
XL
279 let trait_ref = tcx.erase_late_bound_regions(&trait_ref);
280 let trait_self_ty = trait_ref.self_ty();
281
282 let mut self_match_impls = vec![];
283 let mut fuzzy_match_impls = vec![];
284
041b39d2
XL
285 self.tcx.for_each_relevant_impl(
286 trait_ref.def_id, trait_self_ty, |def_id| {
9e0c209e 287 let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
a7813a04
XL
288 let impl_trait_ref = tcx
289 .impl_trait_ref(def_id)
290 .unwrap()
9e0c209e 291 .subst(tcx, impl_substs);
a7813a04
XL
292
293 let impl_self_ty = impl_trait_ref.self_ty();
294
7cac9316 295 if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) {
a7813a04
XL
296 self_match_impls.push(def_id);
297
9e0c209e
SL
298 if trait_ref.substs.types().skip(1)
299 .zip(impl_trait_ref.substs.types().skip(1))
a7813a04
XL
300 .all(|(u,v)| self.fuzzy_match_tys(u, v))
301 {
302 fuzzy_match_impls.push(def_id);
303 }
304 }
305 });
306
307 let impl_def_id = if self_match_impls.len() == 1 {
308 self_match_impls[0]
309 } else if fuzzy_match_impls.len() == 1 {
310 fuzzy_match_impls[0]
311 } else {
312 return None
313 };
314
315 if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") {
316 Some(impl_def_id)
317 } else {
318 None
319 }
1a4d82fc 320 }
1a4d82fc 321
ea8adc8c
XL
322 fn on_unimplemented_note(
323 &self,
324 trait_ref: ty::PolyTraitRef<'tcx>,
325 obligation: &PredicateObligation<'tcx>) ->
326 OnUnimplementedNote
327 {
a7813a04
XL
328 let def_id = self.impl_similar_to(trait_ref, obligation)
329 .unwrap_or(trait_ref.def_id());
ea8adc8c
XL
330 let trait_ref = *trait_ref.skip_binder();
331
332 let desugaring;
333 let method;
334 let mut flags = vec![];
335 let direct = match obligation.cause.code {
336 ObligationCauseCode::BuiltinDerivedObligation(..) |
337 ObligationCauseCode::ImplDerivedObligation(..) => false,
338 _ => true
339 };
340 if direct {
341 // this is a "direct", user-specified, rather than derived,
342 // obligation.
343 flags.push(("direct", None));
344 }
a7813a04 345
ea8adc8c
XL
346 if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
347 // FIXME: maybe also have some way of handling methods
348 // from other traits? That would require name resolution,
349 // which we might want to be some sort of hygienic.
350 //
351 // Currently I'm leaving it for what I need for `try`.
352 if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
353 method = self.tcx.item_name(item);
354 flags.push(("from_method", None));
355 flags.push(("from_method", Some(&*method)));
85aaf69f 356 }
85aaf69f 357 }
ea8adc8c
XL
358
359 if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
360 desugaring = k.as_symbol().as_str();
361 flags.push(("from_desugaring", None));
362 flags.push(("from_desugaring", Some(&*desugaring)));
363 }
364
365 if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
366 self.tcx, trait_ref.def_id, def_id
367 ) {
368 command.evaluate(self.tcx, trait_ref, &flags)
369 } else {
370 OnUnimplementedNote::empty()
371 }
85aaf69f 372 }
85aaf69f 373
a7813a04
XL
374 fn find_similar_impl_candidates(&self,
375 trait_ref: ty::PolyTraitRef<'tcx>)
376 -> Vec<ty::TraitRef<'tcx>>
377 {
378 let simp = fast_reject::simplify_type(self.tcx,
379 trait_ref.skip_binder().self_ty(),
380 true);
381 let mut impl_candidates = Vec::new();
a7813a04
XL
382
383 match simp {
041b39d2 384 Some(simp) => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
a7813a04
XL
385 let imp = self.tcx.impl_trait_ref(def_id).unwrap();
386 let imp_simp = fast_reject::simplify_type(self.tcx,
387 imp.self_ty(),
388 true);
389 if let Some(imp_simp) = imp_simp {
390 if simp != imp_simp {
391 return;
392 }
54a0048b 393 }
a7813a04
XL
394 impl_candidates.push(imp);
395 }),
041b39d2 396 None => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
a7813a04
XL
397 impl_candidates.push(
398 self.tcx.impl_trait_ref(def_id).unwrap());
399 })
400 };
401 impl_candidates
402 }
54a0048b 403
a7813a04 404 fn report_similar_impl_candidates(&self,
8bb4bdeb 405 impl_candidates: Vec<ty::TraitRef<'tcx>>,
a7813a04
XL
406 err: &mut DiagnosticBuilder)
407 {
a7813a04
XL
408 if impl_candidates.is_empty() {
409 return;
410 }
411
8bb4bdeb
XL
412 let end = if impl_candidates.len() <= 5 {
413 impl_candidates.len()
414 } else {
415 4
416 };
32a655c1
SL
417 err.help(&format!("the following implementations were found:{}{}",
418 &impl_candidates[0..end].iter().map(|candidate| {
419 format!("\n {:?}", candidate)
420 }).collect::<String>(),
8bb4bdeb 421 if impl_candidates.len() > 5 {
32a655c1
SL
422 format!("\nand {} others", impl_candidates.len() - 4)
423 } else {
424 "".to_owned()
425 }
426 ));
7453a54e 427 }
c34b1796 428
a7813a04
XL
429 /// Reports that an overflow has occurred and halts compilation. We
430 /// halt compilation unconditionally because it is important that
431 /// overflows never be masked -- they basically represent computations
432 /// whose result could not be truly determined and thus we can't say
433 /// if the program type checks or not -- and they are unusual
434 /// occurrences in any case.
435 pub fn report_overflow_error<T>(&self,
436 obligation: &Obligation<'tcx, T>,
437 suggest_increasing_limit: bool) -> !
438 where T: fmt::Display + TypeFoldable<'tcx>
439 {
440 let predicate =
441 self.resolve_type_vars_if_possible(&obligation.predicate);
442 let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
443 "overflow evaluating the requirement `{}`",
444 predicate);
c34b1796 445
a7813a04
XL
446 if suggest_increasing_limit {
447 self.suggest_new_overflow_limit(&mut err);
448 }
c34b1796 449
a7813a04 450 self.note_obligation_cause(&mut err, obligation);
7453a54e 451
a7813a04
XL
452 err.emit();
453 self.tcx.sess.abort_if_errors();
454 bug!();
455 }
7453a54e 456
a7813a04
XL
457 /// Reports that a cycle was detected which led to overflow and halts
458 /// compilation. This is equivalent to `report_overflow_error` except
459 /// that we can give a more helpful error message (and, in particular,
460 /// we do not suggest increasing the overflow limit, which is not
461 /// going to help).
462 pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
463 let cycle = self.resolve_type_vars_if_possible(&cycle.to_owned());
464 assert!(cycle.len() > 0);
7453a54e 465
a7813a04 466 debug!("report_overflow_error_cycle: cycle={:?}", cycle);
7453a54e 467
a7813a04
XL
468 self.report_overflow_error(&cycle[0], false);
469 }
7453a54e 470
c30ab7b3
SL
471 pub fn report_extra_impl_obligation(&self,
472 error_span: Span,
473 item_name: ast::Name,
474 _impl_item_def_id: DefId,
475 trait_item_def_id: DefId,
476 requirement: &fmt::Display,
477 lint_id: Option<ast::NodeId>) // (*)
478 -> DiagnosticBuilder<'tcx>
479 {
480 // (*) This parameter is temporary and used only for phasing
481 // in the bug fix to #18937. If it is `Some`, it has a kind of
482 // weird effect -- the diagnostic is reported as a lint, and
483 // the builder which is returned is marked as canceled.
484
3b2f2976
XL
485 let msg = "impl has stricter requirements than trait";
486 let mut err = match lint_id {
487 Some(node_id) => {
488 self.tcx.struct_span_lint_node(EXTRA_REQUIREMENT_IN_IMPL,
489 node_id,
490 error_span,
491 msg)
492 }
493 None => {
494 struct_span_err!(self.tcx.sess,
495 error_span,
496 E0276,
497 "{}", msg)
498 }
499 };
c30ab7b3 500
32a655c1 501 if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
cc61c64b 502 let span = self.tcx.sess.codemap().def_span(trait_item_span);
7cac9316 503 err.span_label(span, format!("definition of `{}` from trait", item_name));
c30ab7b3
SL
504 }
505
506 err.span_label(
507 error_span,
7cac9316 508 format!("impl has extra requirement {}", requirement));
c30ab7b3 509
c30ab7b3
SL
510 err
511 }
512
32a655c1
SL
513
514 /// Get the parent trait chain start
515 fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
516 match code {
517 &ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
518 let parent_trait_ref = self.resolve_type_vars_if_possible(
519 &data.parent_trait_ref);
520 match self.get_parent_trait_ref(&data.parent_code) {
521 Some(t) => Some(t),
522 None => Some(format!("{}", parent_trait_ref.0.self_ty())),
523 }
524 }
525 _ => None,
526 }
527 }
528
a7813a04
XL
529 pub fn report_selection_error(&self,
530 obligation: &PredicateObligation<'tcx>,
9e0c209e 531 error: &SelectionError<'tcx>)
a7813a04
XL
532 {
533 let span = obligation.cause.span;
32a655c1 534
a7813a04
XL
535 let mut err = match *error {
536 SelectionError::Unimplemented => {
c30ab7b3
SL
537 if let ObligationCauseCode::CompareImplMethodObligation {
538 item_name, impl_item_def_id, trait_item_def_id, lint_id
539 } = obligation.cause.code {
540 self.report_extra_impl_obligation(
541 span,
542 item_name,
543 impl_item_def_id,
544 trait_item_def_id,
545 &format!("`{}`", obligation.predicate),
546 lint_id)
547 .emit();
a7813a04 548 return;
8bb4bdeb
XL
549 }
550 match obligation.predicate {
551 ty::Predicate::Trait(ref trait_predicate) => {
552 let trait_predicate =
553 self.resolve_type_vars_if_possible(trait_predicate);
7453a54e 554
8bb4bdeb
XL
555 if self.tcx.sess.has_errors() && trait_predicate.references_error() {
556 return;
a7813a04 557 }
8bb4bdeb
XL
558 let trait_ref = trait_predicate.to_poly_trait_ref();
559 let (post_message, pre_message) =
560 self.get_parent_trait_ref(&obligation.cause.code)
561 .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
ea8adc8c
XL
562 .unwrap_or((String::new(), String::new()));
563
564 let OnUnimplementedNote { message, label }
565 = self.on_unimplemented_note(trait_ref, obligation);
566 let have_alt_message = message.is_some() || label.is_some();
567
8bb4bdeb
XL
568 let mut err = struct_span_err!(
569 self.tcx.sess,
570 span,
571 E0277,
ea8adc8c
XL
572 "{}",
573 message.unwrap_or_else(|| {
574 format!("the trait bound `{}` is not satisfied{}",
575 trait_ref.to_predicate(), post_message)
576 }));
8bb4bdeb 577
ea8adc8c 578 if let Some(ref s) = label {
7cac9316
XL
579 // If it has a custom "#[rustc_on_unimplemented]"
580 // error message, let's display it as the label!
581 err.span_label(span, s.as_str());
582 err.help(&format!("{}the trait `{}` is not implemented for `{}`",
583 pre_message,
584 trait_ref,
585 trait_ref.self_ty()));
586 } else {
587 err.span_label(span,
588 &*format!("{}the trait `{}` is not implemented for `{}`",
589 pre_message,
590 trait_ref,
591 trait_ref.self_ty()));
592 }
593
8bb4bdeb 594 // Try to report a help message
8bb4bdeb 595 if !trait_ref.has_infer_types() &&
7cac9316 596 self.predicate_can_apply(obligation.param_env, trait_ref) {
8bb4bdeb
XL
597 // If a where-clause may be useful, remind the
598 // user that they can add it.
599 //
600 // don't display an on-unimplemented note, as
601 // these notes will often be of the form
602 // "the type `T` can't be frobnicated"
603 // which is somewhat confusing.
604 err.help(&format!("consider adding a `where {}` bound",
605 trait_ref.to_predicate()));
ea8adc8c 606 } else if !have_alt_message {
cc61c64b 607 // Can't show anything else useful, try to find similar impls.
8bb4bdeb
XL
608 let impl_candidates = self.find_similar_impl_candidates(trait_ref);
609 self.report_similar_impl_candidates(impl_candidates, &mut err);
a7813a04 610 }
cc61c64b 611
8bb4bdeb
XL
612 err
613 }
7453a54e 614
cc61c64b
XL
615 ty::Predicate::Subtype(ref predicate) => {
616 // Errors for Subtype predicates show up as
617 // `FulfillmentErrorCode::CodeSubtypeError`,
618 // not selection error.
619 span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
620 }
621
8bb4bdeb
XL
622 ty::Predicate::Equate(ref predicate) => {
623 let predicate = self.resolve_type_vars_if_possible(predicate);
624 let err = self.equality_predicate(&obligation.cause,
7cac9316
XL
625 obligation.param_env,
626 &predicate).err().unwrap();
8bb4bdeb
XL
627 struct_span_err!(self.tcx.sess, span, E0278,
628 "the requirement `{}` is not satisfied (`{}`)",
629 predicate, err)
630 }
e9174d1e 631
8bb4bdeb
XL
632 ty::Predicate::RegionOutlives(ref predicate) => {
633 let predicate = self.resolve_type_vars_if_possible(predicate);
634 let err = self.region_outlives_predicate(&obligation.cause,
635 &predicate).err().unwrap();
636 struct_span_err!(self.tcx.sess, span, E0279,
637 "the requirement `{}` is not satisfied (`{}`)",
638 predicate, err)
639 }
85aaf69f 640
8bb4bdeb
XL
641 ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
642 let predicate =
643 self.resolve_type_vars_if_possible(&obligation.predicate);
644 struct_span_err!(self.tcx.sess, span, E0280,
645 "the requirement `{}` is not satisfied",
646 predicate)
647 }
e9174d1e 648
8bb4bdeb
XL
649 ty::Predicate::ObjectSafe(trait_def_id) => {
650 let violations = self.tcx.object_safety_violations(trait_def_id);
651 self.tcx.report_object_safety_error(span,
652 trait_def_id,
653 violations)
654 }
655
656 ty::Predicate::ClosureKind(closure_def_id, kind) => {
657 let found_kind = self.closure_kind(closure_def_id).unwrap();
658 let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap();
041b39d2 659 let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
8bb4bdeb
XL
660 let mut err = struct_span_err!(
661 self.tcx.sess, closure_span, E0525,
662 "expected a closure that implements the `{}` trait, \
663 but this closure only implements `{}`",
664 kind,
665 found_kind);
041b39d2
XL
666
667 err.span_label(
8bb4bdeb 668 obligation.cause.span,
041b39d2
XL
669 format!("the requirement to implement `{}` derives from here", kind));
670
671 // Additional context information explaining why the closure only implements
672 // a particular trait.
673 if let Some(tables) = self.in_progress_tables {
3b2f2976
XL
674 let tables = tables.borrow();
675 let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id);
676 match tables.closure_kinds().get(closure_hir_id) {
041b39d2
XL
677 Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => {
678 err.span_note(span, &format!(
679 "closure is `FnOnce` because it moves the \
680 variable `{}` out of its environment", name));
681 },
682 Some(&(ty::ClosureKind::FnMut, Some((span, name)))) => {
683 err.span_note(span, &format!(
684 "closure is `FnMut` because it mutates the \
685 variable `{}` here", name));
686 },
687 _ => {}
688 }
689 }
690
8bb4bdeb
XL
691 err.emit();
692 return;
693 }
694
695 ty::Predicate::WellFormed(ty) => {
696 // WF predicates cannot themselves make
697 // errors. They can only block due to
698 // ambiguity; otherwise, they always
699 // degenerate into other obligations
700 // (which may fail).
701 span_bug!(span, "WF predicate not satisfied for {:?}", ty);
85aaf69f 702 }
ea8adc8c
XL
703
704 ty::Predicate::ConstEvaluatable(..) => {
705 // Errors for `ConstEvaluatable` predicates show up as
706 // `SelectionError::ConstEvalFailure`,
707 // not `Unimplemented`.
708 span_bug!(span,
709 "const-evaluatable requirement gave wrong error: `{:?}`", obligation)
710 }
1a4d82fc
JJ
711 }
712 }
85aaf69f 713
ea8adc8c 714 OutputTypeParameterMismatch(ref expected_trait_ref, ref actual_trait_ref, _) => {
a7813a04
XL
715 let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
716 let actual_trait_ref = self.resolve_type_vars_if_possible(&*actual_trait_ref);
717 if actual_trait_ref.self_ty().references_error() {
718 return;
719 }
7cac9316
XL
720 let expected_trait_ty = expected_trait_ref.self_ty();
721 let found_span = expected_trait_ty.ty_to_def_id().and_then(|did| {
722 self.tcx.hir.span_if_local(did)
723 });
724
ea8adc8c
XL
725 let self_ty_count =
726 match expected_trait_ref.skip_binder().substs.type_at(1).sty {
727 ty::TyTuple(ref tys, _) => tys.len(),
728 _ => 1,
7cac9316 729 };
ea8adc8c
XL
730 let arg_ty_count =
731 match actual_trait_ref.skip_binder().substs.type_at(1).sty {
732 ty::TyTuple(ref tys, _) => tys.len(),
733 _ => 1,
7cac9316 734 };
ea8adc8c
XL
735 if self_ty_count == arg_ty_count {
736 self.report_closure_arg_mismatch(span,
737 found_span,
738 expected_trait_ref,
739 actual_trait_ref)
7cac9316 740 } else {
ea8adc8c
XL
741 // Expected `|| { }`, found `|x, y| { }`
742 // Expected `fn(x) -> ()`, found `|| { }`
743 self.report_arg_count_mismatch(
744 span,
745 found_span,
746 arg_ty_count,
747 self_ty_count,
748 expected_trait_ty.is_closure()
749 )
7cac9316 750 }
1a4d82fc 751 }
d9579d0f 752
a7813a04
XL
753 TraitNotObjectSafe(did) => {
754 let violations = self.tcx.object_safety_violations(did);
9e0c209e
SL
755 self.tcx.report_object_safety_error(span, did,
756 violations)
a7813a04 757 }
ea8adc8c
XL
758
759 ConstEvalFailure(ref err) => {
760 if let const_val::ErrKind::TypeckError = err.kind {
761 return;
762 }
763 err.struct_error(self.tcx, span, "constant expression")
764 }
a7813a04
XL
765 };
766 self.note_obligation_cause(&mut err, obligation);
767 err.emit();
e9174d1e 768 }
7cac9316 769
7cac9316
XL
770 fn report_arg_count_mismatch(&self,
771 span: Span,
772 found_span: Option<Span>,
773 expected: usize,
774 found: usize,
775 is_closure: bool)
776 -> DiagnosticBuilder<'tcx>
777 {
778 let mut err = struct_span_err!(self.tcx.sess, span, E0593,
779 "{} takes {} argument{} but {} argument{} {} required",
780 if is_closure { "closure" } else { "function" },
781 found,
782 if found == 1 { "" } else { "s" },
783 expected,
784 if expected == 1 { "" } else { "s" },
785 if expected == 1 { "is" } else { "are" });
786
787 err.span_label(span, format!("expected {} that takes {} argument{}",
788 if is_closure { "closure" } else { "function" },
789 expected,
790 if expected == 1 { "" } else { "s" }));
791 if let Some(span) = found_span {
792 err.span_label(span, format!("takes {} argument{}",
793 found,
794 if found == 1 { "" } else { "s" }));
795 }
796 err
797 }
ea8adc8c
XL
798
799 fn report_closure_arg_mismatch(&self,
800 span: Span,
801 found_span: Option<Span>,
802 expected_ref: ty::PolyTraitRef<'tcx>,
803 found: ty::PolyTraitRef<'tcx>)
804 -> DiagnosticBuilder<'tcx>
805 {
806 fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
807 trait_ref: &ty::TraitRef<'tcx>) -> String {
808 let inputs = trait_ref.substs.type_at(1);
809 let sig = if let ty::TyTuple(inputs, _) = inputs.sty {
810 tcx.mk_fn_sig(
811 inputs.iter().map(|&x| x),
812 tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
813 false,
814 hir::Unsafety::Normal,
815 ::syntax::abi::Abi::Rust
816 )
817 } else {
818 tcx.mk_fn_sig(
819 ::std::iter::once(inputs),
820 tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
821 false,
822 hir::Unsafety::Normal,
823 ::syntax::abi::Abi::Rust
824 )
825 };
826 format!("{}", ty::Binder(sig))
827 }
828
829 let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
830 let mut err = struct_span_err!(self.tcx.sess, span, E0631,
831 "type mismatch in {} arguments",
832 if argument_is_closure { "closure" } else { "function" });
833
834 let found_str = format!(
835 "expected signature of `{}`",
836 build_fn_sig_string(self.tcx, found.skip_binder())
837 );
838 err.span_label(span, found_str);
839
840 let found_span = found_span.unwrap_or(span);
841 let expected_str = format!(
842 "found signature of `{}`",
843 build_fn_sig_string(self.tcx, expected_ref.skip_binder())
844 );
845 err.span_label(found_span, expected_str);
846
847 err
848 }
e9174d1e 849}
d9579d0f 850
a7813a04
XL
851impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
852 pub fn recursive_type_with_infinite_size_error(self,
853 type_def_id: DefId)
854 -> DiagnosticBuilder<'tcx>
855 {
856 assert!(type_def_id.is_local());
32a655c1 857 let span = self.hir.span_if_local(type_def_id).unwrap();
cc61c64b 858 let span = self.sess.codemap().def_span(span);
a7813a04
XL
859 let mut err = struct_span_err!(self.sess, span, E0072,
860 "recursive type `{}` has infinite size",
861 self.item_path_str(type_def_id));
7cac9316 862 err.span_label(span, "recursive type has infinite size");
a7813a04
XL
863 err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
864 at some point to make `{}` representable",
865 self.item_path_str(type_def_id)));
866 err
867 }
d9579d0f 868
a7813a04
XL
869 pub fn report_object_safety_error(self,
870 span: Span,
871 trait_def_id: DefId,
a7813a04 872 violations: Vec<ObjectSafetyViolation>)
9e0c209e 873 -> DiagnosticBuilder<'tcx>
a7813a04 874 {
9e0c209e 875 let trait_str = self.item_path_str(trait_def_id);
cc61c64b 876 let span = self.sess.codemap().def_span(span);
9e0c209e
SL
877 let mut err = struct_span_err!(
878 self.sess, span, E0038,
879 "the trait `{}` cannot be made into an object",
880 trait_str);
7cac9316 881 err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
d9579d0f 882
476ff2be 883 let mut reported_violations = FxHashSet();
a7813a04
XL
884 for violation in violations {
885 if !reported_violations.insert(violation.clone()) {
886 continue;
e9174d1e 887 }
8bb4bdeb 888 err.note(&violation.error_msg());
d9579d0f 889 }
a7813a04 890 err
1a4d82fc
JJ
891 }
892}
893
a7813a04 894impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
041b39d2
XL
895 fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
896 body_id: Option<hir::BodyId>) {
a7813a04
XL
897 // Unable to successfully determine, probably means
898 // insufficient type information, but could mean
899 // ambiguous impls. The latter *ought* to be a
900 // coherence violation, so we don't report it here.
901
902 let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
cc61c64b 903 let span = obligation.cause.span;
a7813a04
XL
904
905 debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
906 predicate,
907 obligation);
908
909 // Ambiguity errors are often caused as fallout from earlier
910 // errors. So just ignore them if this infcx is tainted.
911 if self.is_tainted_by_errors() {
912 return;
913 }
914
915 match predicate {
916 ty::Predicate::Trait(ref data) => {
917 let trait_ref = data.to_poly_trait_ref();
918 let self_ty = trait_ref.self_ty();
9e0c209e 919 if predicate.references_error() {
8bb4bdeb
XL
920 return;
921 }
922 // Typically, this ambiguity should only happen if
923 // there are unresolved type inference variables
924 // (otherwise it would suggest a coherence
925 // failure). But given #21974 that is not necessarily
926 // the case -- we can have multiple where clauses that
927 // are only distinguished by a region, which results
928 // in an ambiguity even when all types are fully
929 // known, since we don't dispatch based on region
930 // relationships.
931
932 // This is kind of a hack: it frequently happens that some earlier
933 // error prevents types from being fully inferred, and then we get
934 // a bunch of uninteresting errors saying something like "<generic
935 // #0> doesn't implement Sized". It may even be true that we
936 // could just skip over all checks where the self-ty is an
937 // inference variable, but I was afraid that there might be an
938 // inference variable created, registered as an obligation, and
939 // then never forced by writeback, and hence by skipping here we'd
940 // be ignoring the fact that we don't KNOW the type works
941 // out. Though even that would probably be harmless, given that
942 // we're only talking about builtin traits, which are known to be
943 // inhabited. But in any case I just threw in this check for
944 // has_errors() to be sure that compilation isn't happening
945 // anyway. In that case, why inundate the user.
946 if !self.tcx.sess.has_errors() {
947 if
ea8adc8c 948 self.tcx.lang_items().sized_trait()
8bb4bdeb
XL
949 .map_or(false, |sized_id| sized_id == trait_ref.def_id())
950 {
cc61c64b 951 self.need_type_info(body_id, span, self_ty);
8bb4bdeb
XL
952 } else {
953 let mut err = struct_span_err!(self.tcx.sess,
cc61c64b 954 span, E0283,
8bb4bdeb
XL
955 "type annotations required: \
956 cannot resolve `{}`",
957 predicate);
958 self.note_obligation_cause(&mut err, obligation);
959 err.emit();
1a4d82fc
JJ
960 }
961 }
1a4d82fc 962 }
1a4d82fc 963
a7813a04
XL
964 ty::Predicate::WellFormed(ty) => {
965 // Same hacky approach as above to avoid deluging user
966 // with error messages.
967 if !ty.references_error() && !self.tcx.sess.has_errors() {
cc61c64b
XL
968 self.need_type_info(body_id, span, ty);
969 }
970 }
971
972 ty::Predicate::Subtype(ref data) => {
973 if data.references_error() || self.tcx.sess.has_errors() {
974 // no need to overload user in such cases
975 } else {
976 let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
977 // both must be type variables, or the other would've been instantiated
978 assert!(a.is_ty_var() && b.is_ty_var());
041b39d2 979 self.need_type_info(body_id,
cc61c64b
XL
980 obligation.cause.span,
981 a);
a7813a04 982 }
e9174d1e 983 }
e9174d1e 984
a7813a04
XL
985 _ => {
986 if !self.tcx.sess.has_errors() {
987 let mut err = struct_span_err!(self.tcx.sess,
988 obligation.cause.span, E0284,
989 "type annotations required: \
990 cannot resolve `{}`",
991 predicate);
992 self.note_obligation_cause(&mut err, obligation);
993 err.emit();
994 }
1a4d82fc
JJ
995 }
996 }
997 }
1a4d82fc 998
a7813a04
XL
999 /// Returns whether the trait predicate may apply for *some* assignment
1000 /// to the type parameters.
7cac9316
XL
1001 fn predicate_can_apply(&self,
1002 param_env: ty::ParamEnv<'tcx>,
1003 pred: ty::PolyTraitRef<'tcx>)
1004 -> bool {
a7813a04
XL
1005 struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
1006 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
476ff2be 1007 var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>
a7813a04 1008 }
54a0048b 1009
a7813a04
XL
1010 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ParamToVarFolder<'a, 'gcx, 'tcx> {
1011 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.infcx.tcx }
54a0048b 1012
a7813a04 1013 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
476ff2be 1014 if let ty::TyParam(ty::ParamTy {name, ..}) = ty.sty {
a7813a04 1015 let infcx = self.infcx;
476ff2be
SL
1016 self.var_map.entry(ty).or_insert_with(||
1017 infcx.next_ty_var(
1018 TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, name)))
a7813a04
XL
1019 } else {
1020 ty.super_fold_with(self)
1021 }
54a0048b
SL
1022 }
1023 }
54a0048b 1024
a7813a04
XL
1025 self.probe(|_| {
1026 let mut selcx = SelectionContext::new(self);
54a0048b 1027
a7813a04
XL
1028 let cleaned_pred = pred.fold_with(&mut ParamToVarFolder {
1029 infcx: self,
476ff2be 1030 var_map: FxHashMap()
a7813a04 1031 });
54a0048b 1032
a7813a04
XL
1033 let cleaned_pred = super::project::normalize(
1034 &mut selcx,
7cac9316 1035 param_env,
a7813a04
XL
1036 ObligationCause::dummy(),
1037 &cleaned_pred
1038 ).value;
54a0048b 1039
a7813a04
XL
1040 let obligation = Obligation::new(
1041 ObligationCause::dummy(),
7cac9316 1042 param_env,
a7813a04
XL
1043 cleaned_pred.to_predicate()
1044 );
54a0048b 1045
a7813a04
XL
1046 selcx.evaluate_obligation(&obligation)
1047 })
1048 }
54a0048b 1049
a7813a04
XL
1050 fn note_obligation_cause<T>(&self,
1051 err: &mut DiagnosticBuilder,
1052 obligation: &Obligation<'tcx, T>)
1053 where T: fmt::Display
1054 {
1055 self.note_obligation_cause_code(err,
1056 &obligation.predicate,
1057 &obligation.cause.code);
1058 }
1a4d82fc 1059
a7813a04
XL
1060 fn note_obligation_cause_code<T>(&self,
1061 err: &mut DiagnosticBuilder,
1062 predicate: &T,
1063 cause_code: &ObligationCauseCode<'tcx>)
1064 where T: fmt::Display
1065 {
1066 let tcx = self.tcx;
1067 match *cause_code {
476ff2be
SL
1068 ObligationCauseCode::ExprAssignable |
1069 ObligationCauseCode::MatchExpressionArm { .. } |
1070 ObligationCauseCode::IfExpression |
1071 ObligationCauseCode::IfExpressionWithNoElse |
1072 ObligationCauseCode::EquatePredicate |
1073 ObligationCauseCode::MainFunctionType |
1074 ObligationCauseCode::StartFunctionType |
1075 ObligationCauseCode::IntrinsicType |
1076 ObligationCauseCode::MethodReceiver |
cc61c64b 1077 ObligationCauseCode::ReturnNoExpression |
476ff2be
SL
1078 ObligationCauseCode::MiscObligation => {
1079 }
a7813a04
XL
1080 ObligationCauseCode::SliceOrArrayElem => {
1081 err.note("slice and array elements must have `Sized` type");
1082 }
1083 ObligationCauseCode::TupleElem => {
041b39d2 1084 err.note("only the last element of a tuple may have a dynamically sized type");
a7813a04
XL
1085 }
1086 ObligationCauseCode::ProjectionWf(data) => {
1087 err.note(&format!("required so that the projection `{}` is well-formed",
1088 data));
1089 }
1090 ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
1091 err.note(&format!("required so that reference `{}` does not outlive its referent",
1092 ref_ty));
1093 }
c30ab7b3
SL
1094 ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
1095 err.note(&format!("required so that the lifetime bound of `{}` for `{}` \
1096 is satisfied",
1097 region, object_ty));
1098 }
a7813a04
XL
1099 ObligationCauseCode::ItemObligation(item_def_id) => {
1100 let item_name = tcx.item_path_str(item_def_id);
1101 err.note(&format!("required by `{}`", item_name));
1102 }
1103 ObligationCauseCode::ObjectCastObligation(object_ty) => {
1104 err.note(&format!("required for the cast to the object type `{}`",
1105 self.ty_to_string(object_ty)));
1106 }
1107 ObligationCauseCode::RepeatVec => {
1108 err.note("the `Copy` trait is required because the \
1109 repeated element will be copied");
1110 }
1111 ObligationCauseCode::VariableType(_) => {
1112 err.note("all local variables must have a statically known size");
1113 }
041b39d2 1114 ObligationCauseCode::SizedReturnType => {
a7813a04
XL
1115 err.note("the return type of a function must have a \
1116 statically known size");
1117 }
1118 ObligationCauseCode::AssignmentLhsSized => {
1119 err.note("the left-hand-side of an assignment must have a statically known size");
1120 }
041b39d2
XL
1121 ObligationCauseCode::TupleInitializerSized => {
1122 err.note("tuples must have a statically known size to be initialized");
1123 }
a7813a04
XL
1124 ObligationCauseCode::StructInitializerSized => {
1125 err.note("structs must have a statically known size to be initialized");
1126 }
3b2f2976
XL
1127 ObligationCauseCode::FieldSized(ref item) => {
1128 match *item {
1129 AdtKind::Struct => {
1130 err.note("only the last field of a struct may have a dynamically \
1131 sized type");
1132 }
1133 AdtKind::Union => {
1134 err.note("no field of a union may have a dynamically sized type");
1135 }
1136 AdtKind::Enum => {
1137 err.note("no field of an enum variant may have a dynamically sized type");
1138 }
1139 }
a7813a04 1140 }
3157f602
XL
1141 ObligationCauseCode::ConstSized => {
1142 err.note("constant expressions must have a statically known size");
1143 }
a7813a04
XL
1144 ObligationCauseCode::SharedStatic => {
1145 err.note("shared static variables must have a type that implements `Sync`");
1146 }
1147 ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
1148 let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1149 err.note(&format!("required because it appears within the type `{}`",
1150 parent_trait_ref.0.self_ty()));
1151 let parent_predicate = parent_trait_ref.to_predicate();
1152 self.note_obligation_cause_code(err,
1153 &parent_predicate,
1154 &data.parent_code);
1155 }
1156 ObligationCauseCode::ImplDerivedObligation(ref data) => {
1157 let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1158 err.note(
1159 &format!("required because of the requirements on the impl of `{}` for `{}`",
1160 parent_trait_ref,
1161 parent_trait_ref.0.self_ty()));
1162 let parent_predicate = parent_trait_ref.to_predicate();
1163 self.note_obligation_cause_code(err,
1164 &parent_predicate,
1165 &data.parent_code);
1166 }
c30ab7b3 1167 ObligationCauseCode::CompareImplMethodObligation { .. } => {
a7813a04
XL
1168 err.note(
1169 &format!("the requirement `{}` appears on the impl method \
1170 but not on the corresponding trait method",
1171 predicate));
1172 }
041b39d2
XL
1173 ObligationCauseCode::ReturnType(_) |
1174 ObligationCauseCode::BlockTailExpression(_) => (),
85aaf69f 1175 }
1a4d82fc 1176 }
1a4d82fc 1177
a7813a04
XL
1178 fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder) {
1179 let current_limit = self.tcx.sess.recursion_limit.get();
1180 let suggested_limit = current_limit * 2;
3b2f2976 1181 err.help(&format!("consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
a7813a04
XL
1182 suggested_limit));
1183 }
1a4d82fc 1184}