]> git.proxmox.com Git - rustc.git/blame - src/librustc/traits/error_reporting.rs
New upstream version 1.23.0+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;
8bb4bdeb 36use std::fmt;
041b39d2 37use syntax::ast;
abe05a73 38use session::DiagnosticMessageId;
041b39d2 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 221
abe05a73
XL
222 let msg = format!("type mismatch resolving `{}`", predicate);
223 let error_id = (DiagnosticMessageId::ErrorId(271),
224 Some(obligation.cause.span), msg.clone());
225 let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
226 if fresh {
227 let mut diag = struct_span_err!(
228 self.tcx.sess, obligation.cause.span, E0271,
229 "type mismatch resolving `{}`", predicate
230 );
231 self.note_type_err(&mut diag, &obligation.cause, None, values, err);
232 self.note_obligation_cause(&mut diag, obligation);
233 diag.emit();
234 }
5bcae85e 235 });
a7813a04
XL
236 }
237
a7813a04
XL
238 fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
239 /// returns the fuzzy category of a given type, or None
240 /// if the type can be equated to any type.
241 fn type_category<'tcx>(t: Ty<'tcx>) -> Option<u32> {
242 match t.sty {
243 ty::TyBool => Some(0),
244 ty::TyChar => Some(1),
245 ty::TyStr => Some(2),
9e0c209e 246 ty::TyInt(..) | ty::TyUint(..) | ty::TyInfer(ty::IntVar(..)) => Some(3),
a7813a04 247 ty::TyFloat(..) | ty::TyInfer(ty::FloatVar(..)) => Some(4),
32a655c1 248 ty::TyRef(..) | ty::TyRawPtr(..) => Some(5),
9e0c209e
SL
249 ty::TyArray(..) | ty::TySlice(..) => Some(6),
250 ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(7),
476ff2be 251 ty::TyDynamic(..) => Some(8),
9e0c209e
SL
252 ty::TyClosure(..) => Some(9),
253 ty::TyTuple(..) => Some(10),
254 ty::TyProjection(..) => Some(11),
255 ty::TyParam(..) => Some(12),
256 ty::TyAnon(..) => Some(13),
257 ty::TyNever => Some(14),
258 ty::TyAdt(adt, ..) => match adt.adt_kind() {
259 AdtKind::Struct => Some(15),
260 AdtKind::Union => Some(16),
261 AdtKind::Enum => Some(17),
262 },
ea8adc8c 263 ty::TyGenerator(..) => Some(18),
abe05a73 264 ty::TyForeign(..) => Some(19),
a7813a04
XL
265 ty::TyInfer(..) | ty::TyError => None
266 }
267 }
268
269 match (type_category(a), type_category(b)) {
270 (Some(cat_a), Some(cat_b)) => match (&a.sty, &b.sty) {
9e0c209e 271 (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => def_a == def_b,
a7813a04
XL
272 _ => cat_a == cat_b
273 },
274 // infer and error can be equated to all types
275 _ => true
1a4d82fc
JJ
276 }
277 }
1a4d82fc 278
a7813a04
XL
279 fn impl_similar_to(&self,
280 trait_ref: ty::PolyTraitRef<'tcx>,
281 obligation: &PredicateObligation<'tcx>)
282 -> Option<DefId>
283 {
284 let tcx = self.tcx;
7cac9316 285 let param_env = obligation.param_env;
a7813a04
XL
286 let trait_ref = tcx.erase_late_bound_regions(&trait_ref);
287 let trait_self_ty = trait_ref.self_ty();
288
289 let mut self_match_impls = vec![];
290 let mut fuzzy_match_impls = vec![];
291
041b39d2
XL
292 self.tcx.for_each_relevant_impl(
293 trait_ref.def_id, trait_self_ty, |def_id| {
9e0c209e 294 let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
a7813a04
XL
295 let impl_trait_ref = tcx
296 .impl_trait_ref(def_id)
297 .unwrap()
9e0c209e 298 .subst(tcx, impl_substs);
a7813a04
XL
299
300 let impl_self_ty = impl_trait_ref.self_ty();
301
7cac9316 302 if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) {
a7813a04
XL
303 self_match_impls.push(def_id);
304
9e0c209e
SL
305 if trait_ref.substs.types().skip(1)
306 .zip(impl_trait_ref.substs.types().skip(1))
a7813a04
XL
307 .all(|(u,v)| self.fuzzy_match_tys(u, v))
308 {
309 fuzzy_match_impls.push(def_id);
310 }
311 }
312 });
313
314 let impl_def_id = if self_match_impls.len() == 1 {
315 self_match_impls[0]
316 } else if fuzzy_match_impls.len() == 1 {
317 fuzzy_match_impls[0]
318 } else {
319 return None
320 };
321
322 if tcx.has_attr(impl_def_id, "rustc_on_unimplemented") {
323 Some(impl_def_id)
324 } else {
325 None
326 }
1a4d82fc 327 }
1a4d82fc 328
ea8adc8c
XL
329 fn on_unimplemented_note(
330 &self,
331 trait_ref: ty::PolyTraitRef<'tcx>,
332 obligation: &PredicateObligation<'tcx>) ->
333 OnUnimplementedNote
334 {
a7813a04
XL
335 let def_id = self.impl_similar_to(trait_ref, obligation)
336 .unwrap_or(trait_ref.def_id());
ea8adc8c
XL
337 let trait_ref = *trait_ref.skip_binder();
338
339 let desugaring;
340 let method;
341 let mut flags = vec![];
342 let direct = match obligation.cause.code {
343 ObligationCauseCode::BuiltinDerivedObligation(..) |
344 ObligationCauseCode::ImplDerivedObligation(..) => false,
345 _ => true
346 };
347 if direct {
348 // this is a "direct", user-specified, rather than derived,
349 // obligation.
350 flags.push(("direct", None));
351 }
a7813a04 352
ea8adc8c
XL
353 if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
354 // FIXME: maybe also have some way of handling methods
355 // from other traits? That would require name resolution,
356 // which we might want to be some sort of hygienic.
357 //
358 // Currently I'm leaving it for what I need for `try`.
359 if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
360 method = self.tcx.item_name(item);
361 flags.push(("from_method", None));
362 flags.push(("from_method", Some(&*method)));
85aaf69f 363 }
85aaf69f 364 }
ea8adc8c
XL
365
366 if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
367 desugaring = k.as_symbol().as_str();
368 flags.push(("from_desugaring", None));
369 flags.push(("from_desugaring", Some(&*desugaring)));
370 }
371
372 if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
373 self.tcx, trait_ref.def_id, def_id
374 ) {
375 command.evaluate(self.tcx, trait_ref, &flags)
376 } else {
377 OnUnimplementedNote::empty()
378 }
85aaf69f 379 }
85aaf69f 380
a7813a04
XL
381 fn find_similar_impl_candidates(&self,
382 trait_ref: ty::PolyTraitRef<'tcx>)
383 -> Vec<ty::TraitRef<'tcx>>
384 {
385 let simp = fast_reject::simplify_type(self.tcx,
386 trait_ref.skip_binder().self_ty(),
387 true);
388 let mut impl_candidates = Vec::new();
a7813a04
XL
389
390 match simp {
041b39d2 391 Some(simp) => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
a7813a04
XL
392 let imp = self.tcx.impl_trait_ref(def_id).unwrap();
393 let imp_simp = fast_reject::simplify_type(self.tcx,
394 imp.self_ty(),
395 true);
396 if let Some(imp_simp) = imp_simp {
397 if simp != imp_simp {
398 return;
399 }
54a0048b 400 }
a7813a04
XL
401 impl_candidates.push(imp);
402 }),
041b39d2 403 None => self.tcx.for_each_impl(trait_ref.def_id(), |def_id| {
a7813a04
XL
404 impl_candidates.push(
405 self.tcx.impl_trait_ref(def_id).unwrap());
406 })
407 };
408 impl_candidates
409 }
54a0048b 410
a7813a04 411 fn report_similar_impl_candidates(&self,
8bb4bdeb 412 impl_candidates: Vec<ty::TraitRef<'tcx>>,
a7813a04
XL
413 err: &mut DiagnosticBuilder)
414 {
a7813a04
XL
415 if impl_candidates.is_empty() {
416 return;
417 }
418
8bb4bdeb
XL
419 let end = if impl_candidates.len() <= 5 {
420 impl_candidates.len()
421 } else {
422 4
423 };
32a655c1
SL
424 err.help(&format!("the following implementations were found:{}{}",
425 &impl_candidates[0..end].iter().map(|candidate| {
426 format!("\n {:?}", candidate)
427 }).collect::<String>(),
8bb4bdeb 428 if impl_candidates.len() > 5 {
32a655c1
SL
429 format!("\nand {} others", impl_candidates.len() - 4)
430 } else {
431 "".to_owned()
432 }
433 ));
7453a54e 434 }
c34b1796 435
a7813a04
XL
436 /// Reports that an overflow has occurred and halts compilation. We
437 /// halt compilation unconditionally because it is important that
438 /// overflows never be masked -- they basically represent computations
439 /// whose result could not be truly determined and thus we can't say
440 /// if the program type checks or not -- and they are unusual
441 /// occurrences in any case.
442 pub fn report_overflow_error<T>(&self,
443 obligation: &Obligation<'tcx, T>,
444 suggest_increasing_limit: bool) -> !
445 where T: fmt::Display + TypeFoldable<'tcx>
446 {
447 let predicate =
448 self.resolve_type_vars_if_possible(&obligation.predicate);
449 let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
450 "overflow evaluating the requirement `{}`",
451 predicate);
c34b1796 452
a7813a04
XL
453 if suggest_increasing_limit {
454 self.suggest_new_overflow_limit(&mut err);
455 }
c34b1796 456
a7813a04 457 self.note_obligation_cause(&mut err, obligation);
7453a54e 458
a7813a04
XL
459 err.emit();
460 self.tcx.sess.abort_if_errors();
461 bug!();
462 }
7453a54e 463
a7813a04
XL
464 /// Reports that a cycle was detected which led to overflow and halts
465 /// compilation. This is equivalent to `report_overflow_error` except
466 /// that we can give a more helpful error message (and, in particular,
467 /// we do not suggest increasing the overflow limit, which is not
468 /// going to help).
469 pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
470 let cycle = self.resolve_type_vars_if_possible(&cycle.to_owned());
471 assert!(cycle.len() > 0);
7453a54e 472
a7813a04 473 debug!("report_overflow_error_cycle: cycle={:?}", cycle);
7453a54e 474
a7813a04
XL
475 self.report_overflow_error(&cycle[0], false);
476 }
7453a54e 477
c30ab7b3
SL
478 pub fn report_extra_impl_obligation(&self,
479 error_span: Span,
480 item_name: ast::Name,
481 _impl_item_def_id: DefId,
482 trait_item_def_id: DefId,
abe05a73 483 requirement: &fmt::Display)
c30ab7b3
SL
484 -> DiagnosticBuilder<'tcx>
485 {
3b2f2976 486 let msg = "impl has stricter requirements than trait";
abe05a73
XL
487 let mut err = struct_span_err!(self.tcx.sess,
488 error_span,
489 E0276,
490 "{}", msg);
c30ab7b3 491
32a655c1 492 if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
cc61c64b 493 let span = self.tcx.sess.codemap().def_span(trait_item_span);
7cac9316 494 err.span_label(span, format!("definition of `{}` from trait", item_name));
c30ab7b3
SL
495 }
496
497 err.span_label(
498 error_span,
7cac9316 499 format!("impl has extra requirement {}", requirement));
c30ab7b3 500
c30ab7b3
SL
501 err
502 }
503
32a655c1
SL
504
505 /// Get the parent trait chain start
506 fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
507 match code {
508 &ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
509 let parent_trait_ref = self.resolve_type_vars_if_possible(
510 &data.parent_trait_ref);
511 match self.get_parent_trait_ref(&data.parent_code) {
512 Some(t) => Some(t),
513 None => Some(format!("{}", parent_trait_ref.0.self_ty())),
514 }
515 }
516 _ => None,
517 }
518 }
519
a7813a04
XL
520 pub fn report_selection_error(&self,
521 obligation: &PredicateObligation<'tcx>,
9e0c209e 522 error: &SelectionError<'tcx>)
a7813a04
XL
523 {
524 let span = obligation.cause.span;
32a655c1 525
a7813a04
XL
526 let mut err = match *error {
527 SelectionError::Unimplemented => {
c30ab7b3 528 if let ObligationCauseCode::CompareImplMethodObligation {
abe05a73 529 item_name, impl_item_def_id, trait_item_def_id,
c30ab7b3
SL
530 } = obligation.cause.code {
531 self.report_extra_impl_obligation(
532 span,
533 item_name,
534 impl_item_def_id,
535 trait_item_def_id,
abe05a73 536 &format!("`{}`", obligation.predicate))
c30ab7b3 537 .emit();
a7813a04 538 return;
8bb4bdeb
XL
539 }
540 match obligation.predicate {
541 ty::Predicate::Trait(ref trait_predicate) => {
542 let trait_predicate =
543 self.resolve_type_vars_if_possible(trait_predicate);
7453a54e 544
8bb4bdeb
XL
545 if self.tcx.sess.has_errors() && trait_predicate.references_error() {
546 return;
a7813a04 547 }
8bb4bdeb
XL
548 let trait_ref = trait_predicate.to_poly_trait_ref();
549 let (post_message, pre_message) =
550 self.get_parent_trait_ref(&obligation.cause.code)
551 .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
ea8adc8c
XL
552 .unwrap_or((String::new(), String::new()));
553
554 let OnUnimplementedNote { message, label }
555 = self.on_unimplemented_note(trait_ref, obligation);
556 let have_alt_message = message.is_some() || label.is_some();
557
8bb4bdeb
XL
558 let mut err = struct_span_err!(
559 self.tcx.sess,
560 span,
561 E0277,
ea8adc8c
XL
562 "{}",
563 message.unwrap_or_else(|| {
564 format!("the trait bound `{}` is not satisfied{}",
565 trait_ref.to_predicate(), post_message)
566 }));
8bb4bdeb 567
ea8adc8c 568 if let Some(ref s) = label {
7cac9316
XL
569 // If it has a custom "#[rustc_on_unimplemented]"
570 // error message, let's display it as the label!
571 err.span_label(span, s.as_str());
572 err.help(&format!("{}the trait `{}` is not implemented for `{}`",
573 pre_message,
574 trait_ref,
575 trait_ref.self_ty()));
576 } else {
577 err.span_label(span,
578 &*format!("{}the trait `{}` is not implemented for `{}`",
579 pre_message,
580 trait_ref,
581 trait_ref.self_ty()));
582 }
583
8bb4bdeb 584 // Try to report a help message
8bb4bdeb 585 if !trait_ref.has_infer_types() &&
7cac9316 586 self.predicate_can_apply(obligation.param_env, trait_ref) {
8bb4bdeb
XL
587 // If a where-clause may be useful, remind the
588 // user that they can add it.
589 //
590 // don't display an on-unimplemented note, as
591 // these notes will often be of the form
592 // "the type `T` can't be frobnicated"
593 // which is somewhat confusing.
594 err.help(&format!("consider adding a `where {}` bound",
595 trait_ref.to_predicate()));
ea8adc8c 596 } else if !have_alt_message {
cc61c64b 597 // Can't show anything else useful, try to find similar impls.
8bb4bdeb
XL
598 let impl_candidates = self.find_similar_impl_candidates(trait_ref);
599 self.report_similar_impl_candidates(impl_candidates, &mut err);
a7813a04 600 }
cc61c64b 601
8bb4bdeb
XL
602 err
603 }
7453a54e 604
cc61c64b
XL
605 ty::Predicate::Subtype(ref predicate) => {
606 // Errors for Subtype predicates show up as
607 // `FulfillmentErrorCode::CodeSubtypeError`,
608 // not selection error.
609 span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
610 }
611
8bb4bdeb
XL
612 ty::Predicate::Equate(ref predicate) => {
613 let predicate = self.resolve_type_vars_if_possible(predicate);
614 let err = self.equality_predicate(&obligation.cause,
7cac9316
XL
615 obligation.param_env,
616 &predicate).err().unwrap();
8bb4bdeb
XL
617 struct_span_err!(self.tcx.sess, span, E0278,
618 "the requirement `{}` is not satisfied (`{}`)",
619 predicate, err)
620 }
e9174d1e 621
8bb4bdeb
XL
622 ty::Predicate::RegionOutlives(ref predicate) => {
623 let predicate = self.resolve_type_vars_if_possible(predicate);
624 let err = self.region_outlives_predicate(&obligation.cause,
625 &predicate).err().unwrap();
626 struct_span_err!(self.tcx.sess, span, E0279,
627 "the requirement `{}` is not satisfied (`{}`)",
628 predicate, err)
629 }
85aaf69f 630
8bb4bdeb
XL
631 ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
632 let predicate =
633 self.resolve_type_vars_if_possible(&obligation.predicate);
634 struct_span_err!(self.tcx.sess, span, E0280,
635 "the requirement `{}` is not satisfied",
636 predicate)
637 }
e9174d1e 638
8bb4bdeb
XL
639 ty::Predicate::ObjectSafe(trait_def_id) => {
640 let violations = self.tcx.object_safety_violations(trait_def_id);
641 self.tcx.report_object_safety_error(span,
642 trait_def_id,
643 violations)
644 }
645
646 ty::Predicate::ClosureKind(closure_def_id, kind) => {
647 let found_kind = self.closure_kind(closure_def_id).unwrap();
648 let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap();
041b39d2 649 let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
8bb4bdeb
XL
650 let mut err = struct_span_err!(
651 self.tcx.sess, closure_span, E0525,
652 "expected a closure that implements the `{}` trait, \
653 but this closure only implements `{}`",
654 kind,
655 found_kind);
041b39d2
XL
656
657 err.span_label(
8bb4bdeb 658 obligation.cause.span,
041b39d2
XL
659 format!("the requirement to implement `{}` derives from here", kind));
660
661 // Additional context information explaining why the closure only implements
662 // a particular trait.
663 if let Some(tables) = self.in_progress_tables {
3b2f2976
XL
664 let tables = tables.borrow();
665 let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id);
666 match tables.closure_kinds().get(closure_hir_id) {
041b39d2
XL
667 Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => {
668 err.span_note(span, &format!(
669 "closure is `FnOnce` because it moves the \
670 variable `{}` out of its environment", name));
671 },
672 Some(&(ty::ClosureKind::FnMut, Some((span, name)))) => {
673 err.span_note(span, &format!(
674 "closure is `FnMut` because it mutates the \
675 variable `{}` here", name));
676 },
677 _ => {}
678 }
679 }
680
8bb4bdeb
XL
681 err.emit();
682 return;
683 }
684
685 ty::Predicate::WellFormed(ty) => {
686 // WF predicates cannot themselves make
687 // errors. They can only block due to
688 // ambiguity; otherwise, they always
689 // degenerate into other obligations
690 // (which may fail).
691 span_bug!(span, "WF predicate not satisfied for {:?}", ty);
85aaf69f 692 }
ea8adc8c
XL
693
694 ty::Predicate::ConstEvaluatable(..) => {
695 // Errors for `ConstEvaluatable` predicates show up as
696 // `SelectionError::ConstEvalFailure`,
697 // not `Unimplemented`.
698 span_bug!(span,
699 "const-evaluatable requirement gave wrong error: `{:?}`", obligation)
700 }
1a4d82fc
JJ
701 }
702 }
85aaf69f 703
abe05a73
XL
704 OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => {
705 let found_trait_ref = self.resolve_type_vars_if_possible(&*found_trait_ref);
a7813a04 706 let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
abe05a73 707 if expected_trait_ref.self_ty().references_error() {
a7813a04
XL
708 return;
709 }
abe05a73
XL
710 let found_trait_ty = found_trait_ref.self_ty();
711
712 let found_did = found_trait_ty.ty_to_def_id();
713 let found_span = found_did.and_then(|did| {
7cac9316
XL
714 self.tcx.hir.span_if_local(did)
715 });
716
abe05a73
XL
717 let found_ty_count =
718 match found_trait_ref.skip_binder().substs.type_at(1).sty {
ea8adc8c
XL
719 ty::TyTuple(ref tys, _) => tys.len(),
720 _ => 1,
7cac9316 721 };
abe05a73
XL
722 let (expected_tys, expected_ty_count) =
723 match expected_trait_ref.skip_binder().substs.type_at(1).sty {
724 ty::TyTuple(ref tys, _) =>
725 (tys.iter().map(|t| &t.sty).collect(), tys.len()),
726 ref sty => (vec![sty], 1),
7cac9316 727 };
abe05a73 728 if found_ty_count == expected_ty_count {
ea8adc8c
XL
729 self.report_closure_arg_mismatch(span,
730 found_span,
abe05a73
XL
731 found_trait_ref,
732 expected_trait_ref)
7cac9316 733 } else {
abe05a73
XL
734 let expected_tuple = if expected_ty_count == 1 {
735 expected_tys.first().and_then(|t| {
736 if let &&ty::TyTuple(ref tuptys, _) = t {
737 Some(tuptys.len())
738 } else {
739 None
740 }
741 })
742 } else {
743 None
744 };
745
746 // FIXME(#44150): Expand this to "N args expected but a N-tuple found."
747 // Type of the 1st expected argument is somehow provided as type of a
748 // found one in that case.
749 //
750 // ```
751 // [1i32, 2, 3].sort_by(|(a, b)| ..)
752 // // ^^^^^^^^
753 // // expected_trait_ref: std::ops::FnMut<(&i32, &i32)>
754 // // found_trait_ref: std::ops::FnMut<(&i32,)>
755 // ```
756
757 let (closure_span, closure_args) = found_did
758 .and_then(|did| self.tcx.hir.get_if_local(did))
759 .and_then(|node| {
760 if let hir::map::NodeExpr(
761 &hir::Expr {
762 node: hir::ExprClosure(_, ref decl, id, span, _),
763 ..
764 }) = node
765 {
766 let ty_snips = decl.inputs.iter()
767 .map(|ty| {
768 self.tcx.sess.codemap().span_to_snippet(ty.span).ok()
769 .and_then(|snip| {
770 // filter out dummy spans
771 if snip == "," || snip == "|" {
772 None
773 } else {
774 Some(snip)
775 }
776 })
777 })
778 .collect::<Vec<Option<String>>>();
779
780 let body = self.tcx.hir.body(id);
781 let pat_snips = body.arguments.iter()
782 .map(|arg|
783 self.tcx.sess.codemap().span_to_snippet(arg.pat.span).ok())
784 .collect::<Option<Vec<String>>>();
785
786 Some((span, pat_snips, ty_snips))
787 } else {
788 None
789 }
790 })
791 .map(|(span, pat, ty)| (Some(span), Some((pat, ty))))
792 .unwrap_or((None, None));
793 let closure_args = closure_args.and_then(|(pat, ty)| Some((pat?, ty)));
794
ea8adc8c
XL
795 self.report_arg_count_mismatch(
796 span,
abe05a73
XL
797 closure_span.or(found_span),
798 expected_ty_count,
799 expected_tuple,
800 found_ty_count,
801 closure_args,
802 found_trait_ty.is_closure()
ea8adc8c 803 )
7cac9316 804 }
1a4d82fc 805 }
d9579d0f 806
a7813a04
XL
807 TraitNotObjectSafe(did) => {
808 let violations = self.tcx.object_safety_violations(did);
9e0c209e
SL
809 self.tcx.report_object_safety_error(span, did,
810 violations)
a7813a04 811 }
ea8adc8c
XL
812
813 ConstEvalFailure(ref err) => {
814 if let const_val::ErrKind::TypeckError = err.kind {
815 return;
816 }
817 err.struct_error(self.tcx, span, "constant expression")
818 }
a7813a04
XL
819 };
820 self.note_obligation_cause(&mut err, obligation);
821 err.emit();
e9174d1e 822 }
7cac9316 823
abe05a73
XL
824 fn report_arg_count_mismatch(
825 &self,
826 span: Span,
827 found_span: Option<Span>,
828 expected: usize,
829 expected_tuple: Option<usize>,
830 found: usize,
831 closure_args: Option<(Vec<String>, Vec<Option<String>>)>,
832 is_closure: bool
833 ) -> DiagnosticBuilder<'tcx> {
834 use std::borrow::Cow;
835
836 let kind = if is_closure { "closure" } else { "function" };
837
838 let args_str = |n, distinct| format!(
839 "{} {}argument{}",
840 n,
841 if distinct && n >= 2 { "distinct " } else { "" },
842 if n == 1 { "" } else { "s" },
843 );
844
845 let expected_str = if let Some(n) = expected_tuple {
846 assert!(expected == 1);
847 if closure_args.as_ref().map(|&(ref pats, _)| pats.len()) == Some(n) {
848 Cow::from("a single tuple as argument")
849 } else {
850 // be verbose when numbers differ
851 Cow::from(format!("a single {}-tuple as argument", n))
852 }
853 } else {
854 Cow::from(args_str(expected, false))
855 };
856
857 let found_str = if expected_tuple.is_some() {
858 args_str(found, true)
859 } else {
860 args_str(found, false)
861 };
862
863
7cac9316 864 let mut err = struct_span_err!(self.tcx.sess, span, E0593,
abe05a73
XL
865 "{} is expected to take {}, but it takes {}",
866 kind,
867 expected_str,
868 found_str,
869 );
870
871 err.span_label(
872 span,
873 format!(
874 "expected {} that takes {}",
875 kind,
876 expected_str,
877 )
878 );
879
7cac9316 880 if let Some(span) = found_span {
abe05a73
XL
881 if let (Some(expected_tuple), Some((pats, tys))) = (expected_tuple, closure_args) {
882 if expected_tuple != found || pats.len() != found {
883 err.span_label(span, format!("takes {}", found_str));
884 } else {
885 let sugg = format!(
886 "|({}){}|",
887 pats.join(", "),
888
889 // add type annotations if available
890 if tys.iter().any(|ty| ty.is_some()) {
891 Cow::from(format!(
892 ": ({})",
893 tys.into_iter().map(|ty| if let Some(ty) = ty {
894 ty
895 } else {
896 "_".to_string()
897 }).collect::<Vec<String>>().join(", ")
898 ))
899 } else {
900 Cow::from("")
901 },
902 );
903
904 err.span_suggestion(
905 span,
906 "consider changing the closure to accept a tuple",
907 sugg
908 );
909 }
910 } else {
911 err.span_label(span, format!("takes {}", found_str));
912 }
7cac9316 913 }
abe05a73 914
7cac9316
XL
915 err
916 }
ea8adc8c
XL
917
918 fn report_closure_arg_mismatch(&self,
919 span: Span,
920 found_span: Option<Span>,
921 expected_ref: ty::PolyTraitRef<'tcx>,
922 found: ty::PolyTraitRef<'tcx>)
923 -> DiagnosticBuilder<'tcx>
924 {
925 fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
926 trait_ref: &ty::TraitRef<'tcx>) -> String {
927 let inputs = trait_ref.substs.type_at(1);
928 let sig = if let ty::TyTuple(inputs, _) = inputs.sty {
929 tcx.mk_fn_sig(
930 inputs.iter().map(|&x| x),
931 tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
932 false,
933 hir::Unsafety::Normal,
934 ::syntax::abi::Abi::Rust
935 )
936 } else {
937 tcx.mk_fn_sig(
938 ::std::iter::once(inputs),
939 tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
940 false,
941 hir::Unsafety::Normal,
942 ::syntax::abi::Abi::Rust
943 )
944 };
945 format!("{}", ty::Binder(sig))
946 }
947
948 let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
949 let mut err = struct_span_err!(self.tcx.sess, span, E0631,
950 "type mismatch in {} arguments",
951 if argument_is_closure { "closure" } else { "function" });
952
953 let found_str = format!(
954 "expected signature of `{}`",
955 build_fn_sig_string(self.tcx, found.skip_binder())
956 );
957 err.span_label(span, found_str);
958
959 let found_span = found_span.unwrap_or(span);
960 let expected_str = format!(
961 "found signature of `{}`",
962 build_fn_sig_string(self.tcx, expected_ref.skip_binder())
963 );
964 err.span_label(found_span, expected_str);
965
966 err
967 }
e9174d1e 968}
d9579d0f 969
a7813a04
XL
970impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
971 pub fn recursive_type_with_infinite_size_error(self,
972 type_def_id: DefId)
973 -> DiagnosticBuilder<'tcx>
974 {
975 assert!(type_def_id.is_local());
32a655c1 976 let span = self.hir.span_if_local(type_def_id).unwrap();
cc61c64b 977 let span = self.sess.codemap().def_span(span);
a7813a04
XL
978 let mut err = struct_span_err!(self.sess, span, E0072,
979 "recursive type `{}` has infinite size",
980 self.item_path_str(type_def_id));
7cac9316 981 err.span_label(span, "recursive type has infinite size");
a7813a04
XL
982 err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
983 at some point to make `{}` representable",
984 self.item_path_str(type_def_id)));
985 err
986 }
d9579d0f 987
a7813a04
XL
988 pub fn report_object_safety_error(self,
989 span: Span,
990 trait_def_id: DefId,
a7813a04 991 violations: Vec<ObjectSafetyViolation>)
9e0c209e 992 -> DiagnosticBuilder<'tcx>
a7813a04 993 {
9e0c209e 994 let trait_str = self.item_path_str(trait_def_id);
cc61c64b 995 let span = self.sess.codemap().def_span(span);
9e0c209e
SL
996 let mut err = struct_span_err!(
997 self.sess, span, E0038,
998 "the trait `{}` cannot be made into an object",
999 trait_str);
7cac9316 1000 err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
d9579d0f 1001
476ff2be 1002 let mut reported_violations = FxHashSet();
a7813a04
XL
1003 for violation in violations {
1004 if !reported_violations.insert(violation.clone()) {
1005 continue;
e9174d1e 1006 }
8bb4bdeb 1007 err.note(&violation.error_msg());
d9579d0f 1008 }
a7813a04 1009 err
1a4d82fc
JJ
1010 }
1011}
1012
a7813a04 1013impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
041b39d2
XL
1014 fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
1015 body_id: Option<hir::BodyId>) {
a7813a04
XL
1016 // Unable to successfully determine, probably means
1017 // insufficient type information, but could mean
1018 // ambiguous impls. The latter *ought* to be a
1019 // coherence violation, so we don't report it here.
1020
1021 let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
cc61c64b 1022 let span = obligation.cause.span;
a7813a04
XL
1023
1024 debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
1025 predicate,
1026 obligation);
1027
1028 // Ambiguity errors are often caused as fallout from earlier
1029 // errors. So just ignore them if this infcx is tainted.
1030 if self.is_tainted_by_errors() {
1031 return;
1032 }
1033
1034 match predicate {
1035 ty::Predicate::Trait(ref data) => {
1036 let trait_ref = data.to_poly_trait_ref();
1037 let self_ty = trait_ref.self_ty();
9e0c209e 1038 if predicate.references_error() {
8bb4bdeb
XL
1039 return;
1040 }
1041 // Typically, this ambiguity should only happen if
1042 // there are unresolved type inference variables
1043 // (otherwise it would suggest a coherence
1044 // failure). But given #21974 that is not necessarily
1045 // the case -- we can have multiple where clauses that
1046 // are only distinguished by a region, which results
1047 // in an ambiguity even when all types are fully
1048 // known, since we don't dispatch based on region
1049 // relationships.
1050
1051 // This is kind of a hack: it frequently happens that some earlier
1052 // error prevents types from being fully inferred, and then we get
1053 // a bunch of uninteresting errors saying something like "<generic
1054 // #0> doesn't implement Sized". It may even be true that we
1055 // could just skip over all checks where the self-ty is an
1056 // inference variable, but I was afraid that there might be an
1057 // inference variable created, registered as an obligation, and
1058 // then never forced by writeback, and hence by skipping here we'd
1059 // be ignoring the fact that we don't KNOW the type works
1060 // out. Though even that would probably be harmless, given that
1061 // we're only talking about builtin traits, which are known to be
1062 // inhabited. But in any case I just threw in this check for
1063 // has_errors() to be sure that compilation isn't happening
1064 // anyway. In that case, why inundate the user.
1065 if !self.tcx.sess.has_errors() {
1066 if
ea8adc8c 1067 self.tcx.lang_items().sized_trait()
8bb4bdeb
XL
1068 .map_or(false, |sized_id| sized_id == trait_ref.def_id())
1069 {
cc61c64b 1070 self.need_type_info(body_id, span, self_ty);
8bb4bdeb
XL
1071 } else {
1072 let mut err = struct_span_err!(self.tcx.sess,
cc61c64b 1073 span, E0283,
8bb4bdeb
XL
1074 "type annotations required: \
1075 cannot resolve `{}`",
1076 predicate);
1077 self.note_obligation_cause(&mut err, obligation);
1078 err.emit();
1a4d82fc
JJ
1079 }
1080 }
1a4d82fc 1081 }
1a4d82fc 1082
a7813a04
XL
1083 ty::Predicate::WellFormed(ty) => {
1084 // Same hacky approach as above to avoid deluging user
1085 // with error messages.
1086 if !ty.references_error() && !self.tcx.sess.has_errors() {
cc61c64b
XL
1087 self.need_type_info(body_id, span, ty);
1088 }
1089 }
1090
1091 ty::Predicate::Subtype(ref data) => {
1092 if data.references_error() || self.tcx.sess.has_errors() {
1093 // no need to overload user in such cases
1094 } else {
1095 let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
1096 // both must be type variables, or the other would've been instantiated
1097 assert!(a.is_ty_var() && b.is_ty_var());
041b39d2 1098 self.need_type_info(body_id,
cc61c64b
XL
1099 obligation.cause.span,
1100 a);
a7813a04 1101 }
e9174d1e 1102 }
e9174d1e 1103
a7813a04
XL
1104 _ => {
1105 if !self.tcx.sess.has_errors() {
1106 let mut err = struct_span_err!(self.tcx.sess,
1107 obligation.cause.span, E0284,
1108 "type annotations required: \
1109 cannot resolve `{}`",
1110 predicate);
1111 self.note_obligation_cause(&mut err, obligation);
1112 err.emit();
1113 }
1a4d82fc
JJ
1114 }
1115 }
1116 }
1a4d82fc 1117
a7813a04
XL
1118 /// Returns whether the trait predicate may apply for *some* assignment
1119 /// to the type parameters.
7cac9316
XL
1120 fn predicate_can_apply(&self,
1121 param_env: ty::ParamEnv<'tcx>,
1122 pred: ty::PolyTraitRef<'tcx>)
1123 -> bool {
a7813a04
XL
1124 struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
1125 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
476ff2be 1126 var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>
a7813a04 1127 }
54a0048b 1128
a7813a04
XL
1129 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ParamToVarFolder<'a, 'gcx, 'tcx> {
1130 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.infcx.tcx }
54a0048b 1131
a7813a04 1132 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
476ff2be 1133 if let ty::TyParam(ty::ParamTy {name, ..}) = ty.sty {
a7813a04 1134 let infcx = self.infcx;
476ff2be
SL
1135 self.var_map.entry(ty).or_insert_with(||
1136 infcx.next_ty_var(
1137 TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, name)))
a7813a04
XL
1138 } else {
1139 ty.super_fold_with(self)
1140 }
54a0048b
SL
1141 }
1142 }
54a0048b 1143
a7813a04
XL
1144 self.probe(|_| {
1145 let mut selcx = SelectionContext::new(self);
54a0048b 1146
a7813a04
XL
1147 let cleaned_pred = pred.fold_with(&mut ParamToVarFolder {
1148 infcx: self,
476ff2be 1149 var_map: FxHashMap()
a7813a04 1150 });
54a0048b 1151
a7813a04
XL
1152 let cleaned_pred = super::project::normalize(
1153 &mut selcx,
7cac9316 1154 param_env,
a7813a04
XL
1155 ObligationCause::dummy(),
1156 &cleaned_pred
1157 ).value;
54a0048b 1158
a7813a04
XL
1159 let obligation = Obligation::new(
1160 ObligationCause::dummy(),
7cac9316 1161 param_env,
a7813a04
XL
1162 cleaned_pred.to_predicate()
1163 );
54a0048b 1164
a7813a04
XL
1165 selcx.evaluate_obligation(&obligation)
1166 })
1167 }
54a0048b 1168
a7813a04
XL
1169 fn note_obligation_cause<T>(&self,
1170 err: &mut DiagnosticBuilder,
1171 obligation: &Obligation<'tcx, T>)
1172 where T: fmt::Display
1173 {
1174 self.note_obligation_cause_code(err,
1175 &obligation.predicate,
1176 &obligation.cause.code);
1177 }
1a4d82fc 1178
a7813a04
XL
1179 fn note_obligation_cause_code<T>(&self,
1180 err: &mut DiagnosticBuilder,
1181 predicate: &T,
1182 cause_code: &ObligationCauseCode<'tcx>)
1183 where T: fmt::Display
1184 {
1185 let tcx = self.tcx;
1186 match *cause_code {
476ff2be
SL
1187 ObligationCauseCode::ExprAssignable |
1188 ObligationCauseCode::MatchExpressionArm { .. } |
1189 ObligationCauseCode::IfExpression |
1190 ObligationCauseCode::IfExpressionWithNoElse |
1191 ObligationCauseCode::EquatePredicate |
1192 ObligationCauseCode::MainFunctionType |
1193 ObligationCauseCode::StartFunctionType |
1194 ObligationCauseCode::IntrinsicType |
1195 ObligationCauseCode::MethodReceiver |
cc61c64b 1196 ObligationCauseCode::ReturnNoExpression |
476ff2be
SL
1197 ObligationCauseCode::MiscObligation => {
1198 }
a7813a04
XL
1199 ObligationCauseCode::SliceOrArrayElem => {
1200 err.note("slice and array elements must have `Sized` type");
1201 }
1202 ObligationCauseCode::TupleElem => {
041b39d2 1203 err.note("only the last element of a tuple may have a dynamically sized type");
a7813a04
XL
1204 }
1205 ObligationCauseCode::ProjectionWf(data) => {
1206 err.note(&format!("required so that the projection `{}` is well-formed",
1207 data));
1208 }
1209 ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
1210 err.note(&format!("required so that reference `{}` does not outlive its referent",
1211 ref_ty));
1212 }
c30ab7b3
SL
1213 ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
1214 err.note(&format!("required so that the lifetime bound of `{}` for `{}` \
1215 is satisfied",
1216 region, object_ty));
1217 }
a7813a04
XL
1218 ObligationCauseCode::ItemObligation(item_def_id) => {
1219 let item_name = tcx.item_path_str(item_def_id);
1220 err.note(&format!("required by `{}`", item_name));
1221 }
1222 ObligationCauseCode::ObjectCastObligation(object_ty) => {
1223 err.note(&format!("required for the cast to the object type `{}`",
1224 self.ty_to_string(object_ty)));
1225 }
1226 ObligationCauseCode::RepeatVec => {
1227 err.note("the `Copy` trait is required because the \
1228 repeated element will be copied");
1229 }
1230 ObligationCauseCode::VariableType(_) => {
1231 err.note("all local variables must have a statically known size");
1232 }
041b39d2 1233 ObligationCauseCode::SizedReturnType => {
a7813a04
XL
1234 err.note("the return type of a function must have a \
1235 statically known size");
1236 }
1237 ObligationCauseCode::AssignmentLhsSized => {
1238 err.note("the left-hand-side of an assignment must have a statically known size");
1239 }
041b39d2
XL
1240 ObligationCauseCode::TupleInitializerSized => {
1241 err.note("tuples must have a statically known size to be initialized");
1242 }
a7813a04
XL
1243 ObligationCauseCode::StructInitializerSized => {
1244 err.note("structs must have a statically known size to be initialized");
1245 }
3b2f2976
XL
1246 ObligationCauseCode::FieldSized(ref item) => {
1247 match *item {
1248 AdtKind::Struct => {
1249 err.note("only the last field of a struct may have a dynamically \
1250 sized type");
1251 }
1252 AdtKind::Union => {
1253 err.note("no field of a union may have a dynamically sized type");
1254 }
1255 AdtKind::Enum => {
1256 err.note("no field of an enum variant may have a dynamically sized type");
1257 }
1258 }
a7813a04 1259 }
3157f602
XL
1260 ObligationCauseCode::ConstSized => {
1261 err.note("constant expressions must have a statically known size");
1262 }
a7813a04
XL
1263 ObligationCauseCode::SharedStatic => {
1264 err.note("shared static variables must have a type that implements `Sync`");
1265 }
1266 ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
1267 let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1268 err.note(&format!("required because it appears within the type `{}`",
1269 parent_trait_ref.0.self_ty()));
1270 let parent_predicate = parent_trait_ref.to_predicate();
1271 self.note_obligation_cause_code(err,
1272 &parent_predicate,
1273 &data.parent_code);
1274 }
1275 ObligationCauseCode::ImplDerivedObligation(ref data) => {
1276 let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
1277 err.note(
1278 &format!("required because of the requirements on the impl of `{}` for `{}`",
1279 parent_trait_ref,
1280 parent_trait_ref.0.self_ty()));
1281 let parent_predicate = parent_trait_ref.to_predicate();
1282 self.note_obligation_cause_code(err,
1283 &parent_predicate,
1284 &data.parent_code);
1285 }
c30ab7b3 1286 ObligationCauseCode::CompareImplMethodObligation { .. } => {
a7813a04
XL
1287 err.note(
1288 &format!("the requirement `{}` appears on the impl method \
1289 but not on the corresponding trait method",
1290 predicate));
1291 }
041b39d2
XL
1292 ObligationCauseCode::ReturnType(_) |
1293 ObligationCauseCode::BlockTailExpression(_) => (),
85aaf69f 1294 }
1a4d82fc 1295 }
1a4d82fc 1296
a7813a04
XL
1297 fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder) {
1298 let current_limit = self.tcx.sess.recursion_limit.get();
1299 let suggested_limit = current_limit * 2;
3b2f2976 1300 err.help(&format!("consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
a7813a04
XL
1301 suggested_limit));
1302 }
1a4d82fc 1303}