1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 MismatchedProjectionTypes
,
18 OutputTypeParameterMismatch
,
23 ObjectSafetyViolation
,
26 use errors
::DiagnosticBuilder
;
27 use fmt_macros
::{Parser, Piece, Position}
;
28 use hir
::{intravisit, Local, Pat}
;
29 use hir
::intravisit
::{Visitor, NestedVisitorMap}
;
30 use hir
::map
::NodeExpr
;
31 use hir
::def_id
::DefId
;
32 use infer
::{self, InferCtxt}
;
33 use infer
::type_variable
::TypeVariableOrigin
;
34 use rustc
::lint
::builtin
::EXTRA_REQUIREMENT_IN_IMPL
;
37 use ty
::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}
;
38 use ty
::error
::ExpectedFound
;
40 use ty
::fold
::TypeFolder
;
42 use util
::nodemap
::{FxHashMap, FxHashSet}
;
44 use syntax_pos
::{DUMMY_SP, Span}
;
47 #[derive(Debug, PartialEq, Eq, Hash)]
48 pub struct TraitErrorKey
<'tcx
> {
50 predicate
: ty
::Predicate
<'tcx
>
53 impl<'a
, 'gcx
, 'tcx
> TraitErrorKey
<'tcx
> {
54 fn from_error(infcx
: &InferCtxt
<'a
, 'gcx
, 'tcx
>,
55 e
: &FulfillmentError
<'tcx
>) -> Self {
57 infcx
.resolve_type_vars_if_possible(&e
.obligation
.predicate
);
59 span
: e
.obligation
.cause
.span
,
60 predicate
: infcx
.tcx
.erase_regions(&predicate
)
65 struct FindLocalByTypeVisitor
<'a
, 'gcx
: 'a
+ 'tcx
, 'tcx
: 'a
> {
66 infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>,
67 target_ty
: &'a Ty
<'tcx
>,
68 found_pattern
: Option
<&'a Pat
>,
71 impl<'a
, 'gcx
, 'tcx
> Visitor
<'a
> for FindLocalByTypeVisitor
<'a
, 'gcx
, 'tcx
> {
72 fn nested_visit_map
<'this
>(&'this
mut self) -> NestedVisitorMap
<'this
, 'a
> {
73 NestedVisitorMap
::None
76 fn visit_local(&mut self, local
: &'a Local
) {
77 if let Some(&ty
) = self.infcx
.tables
.borrow().node_types
.get(&local
.id
) {
78 let ty
= self.infcx
.resolve_type_vars_if_possible(&ty
);
79 let is_match
= ty
.walk().any(|t
| t
== *self.target_ty
);
81 if is_match
&& self.found_pattern
.is_none() {
82 self.found_pattern
= Some(&*local
.pat
);
85 intravisit
::walk_local(self, local
);
89 impl<'a
, 'gcx
, 'tcx
> InferCtxt
<'a
, 'gcx
, 'tcx
> {
90 pub fn report_fulfillment_errors(&self, errors
: &Vec
<FulfillmentError
<'tcx
>>) {
92 self.report_fulfillment_error(error
);
96 fn report_fulfillment_error(&self,
97 error
: &FulfillmentError
<'tcx
>) {
98 let error_key
= TraitErrorKey
::from_error(self, error
);
99 debug
!("report_fulfillment_errors({:?}) - key={:?}",
101 if !self.reported_trait_errors
.borrow_mut().insert(error_key
) {
102 debug
!("report_fulfillment_errors: skipping duplicate");
106 FulfillmentErrorCode
::CodeSelectionError(ref e
) => {
107 self.report_selection_error(&error
.obligation
, e
);
109 FulfillmentErrorCode
::CodeProjectionError(ref e
) => {
110 self.report_projection_error(&error
.obligation
, e
);
112 FulfillmentErrorCode
::CodeAmbiguity
=> {
113 self.maybe_report_ambiguity(&error
.obligation
);
118 fn report_projection_error(&self,
119 obligation
: &PredicateObligation
<'tcx
>,
120 error
: &MismatchedProjectionTypes
<'tcx
>)
123 self.resolve_type_vars_if_possible(&obligation
.predicate
);
125 if predicate
.references_error() {
131 let mut err
= &error
.err
;
132 let mut values
= None
;
134 // try to find the mismatched types to report the error with.
136 // this can fail if the problem was higher-ranked, in which
137 // cause I have no idea for a good error message.
138 if let ty
::Predicate
::Projection(ref data
) = predicate
{
139 let mut selcx
= SelectionContext
::new(self);
140 let (data
, _
) = self.replace_late_bound_regions_with_fresh_var(
141 obligation
.cause
.span
,
142 infer
::LateBoundRegionConversionTime
::HigherRankedType
,
144 let normalized
= super::normalize_projection_type(
147 obligation
.cause
.clone(),
150 if let Err(error
) = self.eq_types(
151 false, &obligation
.cause
,
152 data
.ty
, normalized
.value
154 values
= Some(infer
::ValuePairs
::Types(ExpectedFound
{
155 expected
: normalized
.value
,
163 let mut diag
= struct_span_err
!(
164 self.tcx
.sess
, obligation
.cause
.span
, E0271
,
165 "type mismatch resolving `{}`", predicate
167 self.note_type_err(&mut diag
, &obligation
.cause
, None
, values
, err
);
168 self.note_obligation_cause(&mut diag
, obligation
);
173 fn fuzzy_match_tys(&self, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> bool
{
174 /// returns the fuzzy category of a given type, or None
175 /// if the type can be equated to any type.
176 fn type_category
<'tcx
>(t
: Ty
<'tcx
>) -> Option
<u32> {
178 ty
::TyBool
=> Some(0),
179 ty
::TyChar
=> Some(1),
180 ty
::TyStr
=> Some(2),
181 ty
::TyInt(..) | ty
::TyUint(..) | ty
::TyInfer(ty
::IntVar(..)) => Some(3),
182 ty
::TyFloat(..) | ty
::TyInfer(ty
::FloatVar(..)) => Some(4),
183 ty
::TyRef(..) | ty
::TyRawPtr(..) => Some(5),
184 ty
::TyArray(..) | ty
::TySlice(..) => Some(6),
185 ty
::TyFnDef(..) | ty
::TyFnPtr(..) => Some(7),
186 ty
::TyDynamic(..) => Some(8),
187 ty
::TyClosure(..) => Some(9),
188 ty
::TyTuple(..) => Some(10),
189 ty
::TyProjection(..) => Some(11),
190 ty
::TyParam(..) => Some(12),
191 ty
::TyAnon(..) => Some(13),
192 ty
::TyNever
=> Some(14),
193 ty
::TyAdt(adt
, ..) => match adt
.adt_kind() {
194 AdtKind
::Struct
=> Some(15),
195 AdtKind
::Union
=> Some(16),
196 AdtKind
::Enum
=> Some(17),
198 ty
::TyInfer(..) | ty
::TyError
=> None
202 match (type_category(a
), type_category(b
)) {
203 (Some(cat_a
), Some(cat_b
)) => match (&a
.sty
, &b
.sty
) {
204 (&ty
::TyAdt(def_a
, _
), &ty
::TyAdt(def_b
, _
)) => def_a
== def_b
,
207 // infer and error can be equated to all types
212 fn impl_similar_to(&self,
213 trait_ref
: ty
::PolyTraitRef
<'tcx
>,
214 obligation
: &PredicateObligation
<'tcx
>)
219 let trait_ref
= tcx
.erase_late_bound_regions(&trait_ref
);
220 let trait_self_ty
= trait_ref
.self_ty();
222 let mut self_match_impls
= vec
![];
223 let mut fuzzy_match_impls
= vec
![];
225 self.tcx
.lookup_trait_def(trait_ref
.def_id
)
226 .for_each_relevant_impl(self.tcx
, trait_self_ty
, |def_id
| {
227 let impl_substs
= self.fresh_substs_for_item(obligation
.cause
.span
, def_id
);
228 let impl_trait_ref
= tcx
229 .impl_trait_ref(def_id
)
231 .subst(tcx
, impl_substs
);
233 let impl_self_ty
= impl_trait_ref
.self_ty();
235 if let Ok(..) = self.can_equate(&trait_self_ty
, &impl_self_ty
) {
236 self_match_impls
.push(def_id
);
238 if trait_ref
.substs
.types().skip(1)
239 .zip(impl_trait_ref
.substs
.types().skip(1))
240 .all(|(u
,v
)| self.fuzzy_match_tys(u
, v
))
242 fuzzy_match_impls
.push(def_id
);
247 let impl_def_id
= if self_match_impls
.len() == 1 {
249 } else if fuzzy_match_impls
.len() == 1 {
255 if tcx
.has_attr(impl_def_id
, "rustc_on_unimplemented") {
262 fn on_unimplemented_note(&self,
263 trait_ref
: ty
::PolyTraitRef
<'tcx
>,
264 obligation
: &PredicateObligation
<'tcx
>) -> Option
<String
> {
265 let def_id
= self.impl_similar_to(trait_ref
, obligation
)
266 .unwrap_or(trait_ref
.def_id());
267 let trait_ref
= trait_ref
.skip_binder();
269 let span
= obligation
.cause
.span
;
270 let mut report
= None
;
271 if let Some(item
) = self.tcx
274 .filter(|a
| a
.check_name("rustc_on_unimplemented"))
277 let err_sp
= item
.meta().span
.substitute_dummy(span
);
278 let trait_str
= self.tcx
.item_path_str(trait_ref
.def_id
);
279 if let Some(istring
) = item
.value_str() {
280 let istring
= &*istring
.as_str();
281 let generics
= self.tcx
.item_generics(trait_ref
.def_id
);
282 let generic_map
= generics
.types
.iter().map(|param
| {
283 (param
.name
.as_str().to_string(),
284 trait_ref
.substs
.type_for_def(param
).to_string())
285 }).collect
::<FxHashMap
<String
, String
>>();
286 let parser
= Parser
::new(istring
);
287 let mut errored
= false;
288 let err
: String
= parser
.filter_map(|p
| {
290 Piece
::String(s
) => Some(s
),
291 Piece
::NextArgument(a
) => match a
.position
{
292 Position
::ArgumentNamed(s
) => match generic_map
.get(s
) {
293 Some(val
) => Some(val
),
295 span_err
!(self.tcx
.sess
, err_sp
, E0272
,
296 "the #[rustc_on_unimplemented] \
298 trait definition for {} refers to \
299 non-existent type parameter {}",
306 span_err
!(self.tcx
.sess
, err_sp
, E0273
,
307 "the #[rustc_on_unimplemented] attribute \
308 on trait definition for {} must have \
309 named format arguments, eg \
310 `#[rustc_on_unimplemented = \
311 \"foo {{T}}\"]`", trait_str
);
318 // Report only if the format string checks out
323 span_err
!(self.tcx
.sess
, err_sp
, E0274
,
324 "the #[rustc_on_unimplemented] attribute on \
325 trait definition for {} must have a value, \
326 eg `#[rustc_on_unimplemented = \"foo\"]`",
333 fn find_similar_impl_candidates(&self,
334 trait_ref
: ty
::PolyTraitRef
<'tcx
>)
335 -> Vec
<ty
::TraitRef
<'tcx
>>
337 let simp
= fast_reject
::simplify_type(self.tcx
,
338 trait_ref
.skip_binder().self_ty(),
340 let mut impl_candidates
= Vec
::new();
341 let trait_def
= self.tcx
.lookup_trait_def(trait_ref
.def_id());
344 Some(simp
) => trait_def
.for_each_impl(self.tcx
, |def_id
| {
345 let imp
= self.tcx
.impl_trait_ref(def_id
).unwrap();
346 let imp_simp
= fast_reject
::simplify_type(self.tcx
,
349 if let Some(imp_simp
) = imp_simp
{
350 if simp
!= imp_simp
{
354 impl_candidates
.push(imp
);
356 None
=> trait_def
.for_each_impl(self.tcx
, |def_id
| {
357 impl_candidates
.push(
358 self.tcx
.impl_trait_ref(def_id
).unwrap());
364 fn report_similar_impl_candidates(&self,
365 impl_candidates
: Vec
<ty
::TraitRef
<'tcx
>>,
366 err
: &mut DiagnosticBuilder
)
368 if impl_candidates
.is_empty() {
372 let end
= if impl_candidates
.len() <= 5 {
373 impl_candidates
.len()
377 err
.help(&format
!("the following implementations were found:{}{}",
378 &impl_candidates
[0..end
].iter().map(|candidate
| {
379 format
!("\n {:?}", candidate
)
380 }).collect
::<String
>(),
381 if impl_candidates
.len() > 5 {
382 format
!("\nand {} others", impl_candidates
.len() - 4)
389 /// Reports that an overflow has occurred and halts compilation. We
390 /// halt compilation unconditionally because it is important that
391 /// overflows never be masked -- they basically represent computations
392 /// whose result could not be truly determined and thus we can't say
393 /// if the program type checks or not -- and they are unusual
394 /// occurrences in any case.
395 pub fn report_overflow_error
<T
>(&self,
396 obligation
: &Obligation
<'tcx
, T
>,
397 suggest_increasing_limit
: bool
) -> !
398 where T
: fmt
::Display
+ TypeFoldable
<'tcx
>
401 self.resolve_type_vars_if_possible(&obligation
.predicate
);
402 let mut err
= struct_span_err
!(self.tcx
.sess
, obligation
.cause
.span
, E0275
,
403 "overflow evaluating the requirement `{}`",
406 if suggest_increasing_limit
{
407 self.suggest_new_overflow_limit(&mut err
);
410 self.note_obligation_cause(&mut err
, obligation
);
413 self.tcx
.sess
.abort_if_errors();
417 /// Reports that a cycle was detected which led to overflow and halts
418 /// compilation. This is equivalent to `report_overflow_error` except
419 /// that we can give a more helpful error message (and, in particular,
420 /// we do not suggest increasing the overflow limit, which is not
422 pub fn report_overflow_error_cycle(&self, cycle
: &[PredicateObligation
<'tcx
>]) -> ! {
423 let cycle
= self.resolve_type_vars_if_possible(&cycle
.to_owned());
424 assert
!(cycle
.len() > 0);
426 debug
!("report_overflow_error_cycle: cycle={:?}", cycle
);
428 self.report_overflow_error(&cycle
[0], false);
431 pub fn report_extra_impl_obligation(&self,
433 item_name
: ast
::Name
,
434 _impl_item_def_id
: DefId
,
435 trait_item_def_id
: DefId
,
436 requirement
: &fmt
::Display
,
437 lint_id
: Option
<ast
::NodeId
>) // (*)
438 -> DiagnosticBuilder
<'tcx
>
440 // (*) This parameter is temporary and used only for phasing
441 // in the bug fix to #18937. If it is `Some`, it has a kind of
442 // weird effect -- the diagnostic is reported as a lint, and
443 // the builder which is returned is marked as canceled.
446 struct_span_err
!(self.tcx
.sess
,
449 "impl has stricter requirements than trait");
451 if let Some(trait_item_span
) = self.tcx
.hir
.span_if_local(trait_item_def_id
) {
452 err
.span_label(trait_item_span
,
453 &format
!("definition of `{}` from trait", item_name
));
458 &format
!("impl has extra requirement {}", requirement
));
460 if let Some(node_id
) = lint_id
{
461 self.tcx
.sess
.add_lint_diagnostic(EXTRA_REQUIREMENT_IN_IMPL
,
471 /// Get the parent trait chain start
472 fn get_parent_trait_ref(&self, code
: &ObligationCauseCode
<'tcx
>) -> Option
<String
> {
474 &ObligationCauseCode
::BuiltinDerivedObligation(ref data
) => {
475 let parent_trait_ref
= self.resolve_type_vars_if_possible(
476 &data
.parent_trait_ref
);
477 match self.get_parent_trait_ref(&data
.parent_code
) {
479 None
=> Some(format
!("{}", parent_trait_ref
.0.self_ty())),
486 pub fn report_selection_error(&self,
487 obligation
: &PredicateObligation
<'tcx
>,
488 error
: &SelectionError
<'tcx
>)
490 let span
= obligation
.cause
.span
;
492 let mut err
= match *error
{
493 SelectionError
::Unimplemented
=> {
494 if let ObligationCauseCode
::CompareImplMethodObligation
{
495 item_name
, impl_item_def_id
, trait_item_def_id
, lint_id
496 } = obligation
.cause
.code
{
497 self.report_extra_impl_obligation(
502 &format
!("`{}`", obligation
.predicate
),
507 match obligation
.predicate
{
508 ty
::Predicate
::Trait(ref trait_predicate
) => {
509 let trait_predicate
=
510 self.resolve_type_vars_if_possible(trait_predicate
);
512 if self.tcx
.sess
.has_errors() && trait_predicate
.references_error() {
515 let trait_ref
= trait_predicate
.to_poly_trait_ref();
516 let (post_message
, pre_message
) =
517 self.get_parent_trait_ref(&obligation
.cause
.code
)
518 .map(|t
| (format
!(" in `{}`", t
), format
!("within `{}`, ", t
)))
519 .unwrap_or((String
::new(), String
::new()));
520 let mut err
= struct_span_err
!(
524 "the trait bound `{}` is not satisfied{}",
525 trait_ref
.to_predicate(),
528 &format
!("{}the trait `{}` is not \
529 implemented for `{}`",
532 trait_ref
.self_ty()));
534 // Try to report a help message
536 if !trait_ref
.has_infer_types() &&
537 self.predicate_can_apply(trait_ref
) {
538 // If a where-clause may be useful, remind the
539 // user that they can add it.
541 // don't display an on-unimplemented note, as
542 // these notes will often be of the form
543 // "the type `T` can't be frobnicated"
544 // which is somewhat confusing.
545 err
.help(&format
!("consider adding a `where {}` bound",
546 trait_ref
.to_predicate()));
547 } else if let Some(s
) = self.on_unimplemented_note(trait_ref
,
549 // If it has a custom "#[rustc_on_unimplemented]"
550 // error message, let's display it!
553 // If we can't show anything useful, try to find
555 let impl_candidates
= self.find_similar_impl_candidates(trait_ref
);
556 self.report_similar_impl_candidates(impl_candidates
, &mut err
);
561 ty
::Predicate
::Equate(ref predicate
) => {
562 let predicate
= self.resolve_type_vars_if_possible(predicate
);
563 let err
= self.equality_predicate(&obligation
.cause
,
564 &predicate
).err().unwrap();
565 struct_span_err
!(self.tcx
.sess
, span
, E0278
,
566 "the requirement `{}` is not satisfied (`{}`)",
570 ty
::Predicate
::RegionOutlives(ref predicate
) => {
571 let predicate
= self.resolve_type_vars_if_possible(predicate
);
572 let err
= self.region_outlives_predicate(&obligation
.cause
,
573 &predicate
).err().unwrap();
574 struct_span_err
!(self.tcx
.sess
, span
, E0279
,
575 "the requirement `{}` is not satisfied (`{}`)",
579 ty
::Predicate
::Projection(..) | ty
::Predicate
::TypeOutlives(..) => {
581 self.resolve_type_vars_if_possible(&obligation
.predicate
);
582 struct_span_err
!(self.tcx
.sess
, span
, E0280
,
583 "the requirement `{}` is not satisfied",
587 ty
::Predicate
::ObjectSafe(trait_def_id
) => {
588 let violations
= self.tcx
.object_safety_violations(trait_def_id
);
589 self.tcx
.report_object_safety_error(span
,
594 ty
::Predicate
::ClosureKind(closure_def_id
, kind
) => {
595 let found_kind
= self.closure_kind(closure_def_id
).unwrap();
596 let closure_span
= self.tcx
.hir
.span_if_local(closure_def_id
).unwrap();
597 let mut err
= struct_span_err
!(
598 self.tcx
.sess
, closure_span
, E0525
,
599 "expected a closure that implements the `{}` trait, \
600 but this closure only implements `{}`",
604 obligation
.cause
.span
,
605 &format
!("the requirement to implement \
606 `{}` derives from here", kind
));
611 ty
::Predicate
::WellFormed(ty
) => {
612 // WF predicates cannot themselves make
613 // errors. They can only block due to
614 // ambiguity; otherwise, they always
615 // degenerate into other obligations
617 span_bug
!(span
, "WF predicate not satisfied for {:?}", ty
);
622 OutputTypeParameterMismatch(ref expected_trait_ref
, ref actual_trait_ref
, ref e
) => {
623 let expected_trait_ref
= self.resolve_type_vars_if_possible(&*expected_trait_ref
);
624 let actual_trait_ref
= self.resolve_type_vars_if_possible(&*actual_trait_ref
);
625 if actual_trait_ref
.self_ty().references_error() {
628 struct_span_err
!(self.tcx
.sess
, span
, E0281
,
629 "type mismatch: the type `{}` implements the trait `{}`, \
630 but the trait `{}` is required ({})",
631 expected_trait_ref
.self_ty(),
637 TraitNotObjectSafe(did
) => {
638 let violations
= self.tcx
.object_safety_violations(did
);
639 self.tcx
.report_object_safety_error(span
, did
,
643 self.note_obligation_cause(&mut err
, obligation
);
648 impl<'a
, 'gcx
, 'tcx
> TyCtxt
<'a
, 'gcx
, 'tcx
> {
649 pub fn recursive_type_with_infinite_size_error(self,
651 -> DiagnosticBuilder
<'tcx
>
653 assert
!(type_def_id
.is_local());
654 let span
= self.hir
.span_if_local(type_def_id
).unwrap();
655 let mut err
= struct_span_err
!(self.sess
, span
, E0072
,
656 "recursive type `{}` has infinite size",
657 self.item_path_str(type_def_id
));
658 err
.span_label(span
, &format
!("recursive type has infinite size"));
659 err
.help(&format
!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
660 at some point to make `{}` representable",
661 self.item_path_str(type_def_id
)));
665 pub fn report_object_safety_error(self,
668 violations
: Vec
<ObjectSafetyViolation
>)
669 -> DiagnosticBuilder
<'tcx
>
671 let trait_str
= self.item_path_str(trait_def_id
);
672 let mut err
= struct_span_err
!(
673 self.sess
, span
, E0038
,
674 "the trait `{}` cannot be made into an object",
676 err
.span_label(span
, &format
!(
677 "the trait `{}` cannot be made into an object", trait_str
680 let mut reported_violations
= FxHashSet();
681 for violation
in violations
{
682 if !reported_violations
.insert(violation
.clone()) {
685 err
.note(&violation
.error_msg());
691 impl<'a
, 'gcx
, 'tcx
> InferCtxt
<'a
, 'gcx
, 'tcx
> {
692 fn maybe_report_ambiguity(&self, obligation
: &PredicateObligation
<'tcx
>) {
693 // Unable to successfully determine, probably means
694 // insufficient type information, but could mean
695 // ambiguous impls. The latter *ought* to be a
696 // coherence violation, so we don't report it here.
698 let predicate
= self.resolve_type_vars_if_possible(&obligation
.predicate
);
700 debug
!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
704 // Ambiguity errors are often caused as fallout from earlier
705 // errors. So just ignore them if this infcx is tainted.
706 if self.is_tainted_by_errors() {
711 ty
::Predicate
::Trait(ref data
) => {
712 let trait_ref
= data
.to_poly_trait_ref();
713 let self_ty
= trait_ref
.self_ty();
714 if predicate
.references_error() {
717 // Typically, this ambiguity should only happen if
718 // there are unresolved type inference variables
719 // (otherwise it would suggest a coherence
720 // failure). But given #21974 that is not necessarily
721 // the case -- we can have multiple where clauses that
722 // are only distinguished by a region, which results
723 // in an ambiguity even when all types are fully
724 // known, since we don't dispatch based on region
727 // This is kind of a hack: it frequently happens that some earlier
728 // error prevents types from being fully inferred, and then we get
729 // a bunch of uninteresting errors saying something like "<generic
730 // #0> doesn't implement Sized". It may even be true that we
731 // could just skip over all checks where the self-ty is an
732 // inference variable, but I was afraid that there might be an
733 // inference variable created, registered as an obligation, and
734 // then never forced by writeback, and hence by skipping here we'd
735 // be ignoring the fact that we don't KNOW the type works
736 // out. Though even that would probably be harmless, given that
737 // we're only talking about builtin traits, which are known to be
738 // inhabited. But in any case I just threw in this check for
739 // has_errors() to be sure that compilation isn't happening
740 // anyway. In that case, why inundate the user.
741 if !self.tcx
.sess
.has_errors() {
743 self.tcx
.lang_items
.sized_trait()
744 .map_or(false, |sized_id
| sized_id
== trait_ref
.def_id())
746 self.need_type_info(obligation
, self_ty
);
748 let mut err
= struct_span_err
!(self.tcx
.sess
,
749 obligation
.cause
.span
, E0283
,
750 "type annotations required: \
751 cannot resolve `{}`",
753 self.note_obligation_cause(&mut err
, obligation
);
759 ty
::Predicate
::WellFormed(ty
) => {
760 // Same hacky approach as above to avoid deluging user
761 // with error messages.
762 if !ty
.references_error() && !self.tcx
.sess
.has_errors() {
763 self.need_type_info(obligation
, ty
);
768 if !self.tcx
.sess
.has_errors() {
769 let mut err
= struct_span_err
!(self.tcx
.sess
,
770 obligation
.cause
.span
, E0284
,
771 "type annotations required: \
772 cannot resolve `{}`",
774 self.note_obligation_cause(&mut err
, obligation
);
781 /// Returns whether the trait predicate may apply for *some* assignment
782 /// to the type parameters.
783 fn predicate_can_apply(&self, pred
: ty
::PolyTraitRef
<'tcx
>) -> bool
{
784 struct ParamToVarFolder
<'a
, 'gcx
: 'a
+'tcx
, 'tcx
: 'a
> {
785 infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>,
786 var_map
: FxHashMap
<Ty
<'tcx
>, Ty
<'tcx
>>
789 impl<'a
, 'gcx
, 'tcx
> TypeFolder
<'gcx
, 'tcx
> for ParamToVarFolder
<'a
, 'gcx
, 'tcx
> {
790 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'b
, 'gcx
, 'tcx
> { self.infcx.tcx }
792 fn fold_ty(&mut self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
793 if let ty
::TyParam(ty
::ParamTy {name, ..}
) = ty
.sty
{
794 let infcx
= self.infcx
;
795 self.var_map
.entry(ty
).or_insert_with(||
797 TypeVariableOrigin
::TypeParameterDefinition(DUMMY_SP
, name
)))
799 ty
.super_fold_with(self)
805 let mut selcx
= SelectionContext
::new(self);
807 let cleaned_pred
= pred
.fold_with(&mut ParamToVarFolder
{
812 let cleaned_pred
= super::project
::normalize(
814 ObligationCause
::dummy(),
818 let obligation
= Obligation
::new(
819 ObligationCause
::dummy(),
820 cleaned_pred
.to_predicate()
823 selcx
.evaluate_obligation(&obligation
)
827 fn extract_type_name(&self, ty
: &'a Ty
<'tcx
>) -> String
{
828 if let ty
::TyInfer(ty
::TyVar(ty_vid
)) = (*ty
).sty
{
829 let ty_vars
= self.type_variables
.borrow();
830 if let TypeVariableOrigin
::TypeParameterDefinition(_
, name
) =
831 *ty_vars
.var_origin(ty_vid
) {
841 fn need_type_info(&self, obligation
: &PredicateObligation
<'tcx
>, ty
: Ty
<'tcx
>) {
842 let ty
= self.resolve_type_vars_if_possible(&ty
);
843 let name
= self.extract_type_name(&ty
);
844 let ref cause
= obligation
.cause
;
846 let mut err
= struct_span_err
!(self.tcx
.sess
,
849 "type annotations needed");
851 err
.span_label(cause
.span
, &format
!("cannot infer type for `{}`", name
));
853 let mut local_visitor
= FindLocalByTypeVisitor
{
859 // #40294: cause.body_id can also be a fn declaration.
860 // Currently, if it's anything other than NodeExpr, we just ignore it
861 match self.tcx
.hir
.find(cause
.body_id
) {
862 Some(NodeExpr(expr
)) => local_visitor
.visit_expr(expr
),
866 if let Some(pattern
) = local_visitor
.found_pattern
{
867 let pattern_span
= pattern
.span
;
868 if let Some(simple_name
) = pattern
.simple_name() {
869 err
.span_label(pattern_span
,
870 &format
!("consider giving `{}` a type",
873 err
.span_label(pattern_span
, &format
!("consider giving a type to pattern"));
880 fn note_obligation_cause
<T
>(&self,
881 err
: &mut DiagnosticBuilder
,
882 obligation
: &Obligation
<'tcx
, T
>)
883 where T
: fmt
::Display
885 self.note_obligation_cause_code(err
,
886 &obligation
.predicate
,
887 &obligation
.cause
.code
);
890 fn note_obligation_cause_code
<T
>(&self,
891 err
: &mut DiagnosticBuilder
,
893 cause_code
: &ObligationCauseCode
<'tcx
>)
894 where T
: fmt
::Display
898 ObligationCauseCode
::ExprAssignable
|
899 ObligationCauseCode
::MatchExpressionArm { .. }
|
900 ObligationCauseCode
::IfExpression
|
901 ObligationCauseCode
::IfExpressionWithNoElse
|
902 ObligationCauseCode
::EquatePredicate
|
903 ObligationCauseCode
::MainFunctionType
|
904 ObligationCauseCode
::StartFunctionType
|
905 ObligationCauseCode
::IntrinsicType
|
906 ObligationCauseCode
::MethodReceiver
|
907 ObligationCauseCode
::MiscObligation
=> {
909 ObligationCauseCode
::SliceOrArrayElem
=> {
910 err
.note("slice and array elements must have `Sized` type");
912 ObligationCauseCode
::TupleElem
=> {
913 err
.note("tuple elements must have `Sized` type");
915 ObligationCauseCode
::ProjectionWf(data
) => {
916 err
.note(&format
!("required so that the projection `{}` is well-formed",
919 ObligationCauseCode
::ReferenceOutlivesReferent(ref_ty
) => {
920 err
.note(&format
!("required so that reference `{}` does not outlive its referent",
923 ObligationCauseCode
::ObjectTypeBound(object_ty
, region
) => {
924 err
.note(&format
!("required so that the lifetime bound of `{}` for `{}` \
928 ObligationCauseCode
::ItemObligation(item_def_id
) => {
929 let item_name
= tcx
.item_path_str(item_def_id
);
930 err
.note(&format
!("required by `{}`", item_name
));
932 ObligationCauseCode
::ObjectCastObligation(object_ty
) => {
933 err
.note(&format
!("required for the cast to the object type `{}`",
934 self.ty_to_string(object_ty
)));
936 ObligationCauseCode
::RepeatVec
=> {
937 err
.note("the `Copy` trait is required because the \
938 repeated element will be copied");
940 ObligationCauseCode
::VariableType(_
) => {
941 err
.note("all local variables must have a statically known size");
943 ObligationCauseCode
::ReturnType
=> {
944 err
.note("the return type of a function must have a \
945 statically known size");
947 ObligationCauseCode
::AssignmentLhsSized
=> {
948 err
.note("the left-hand-side of an assignment must have a statically known size");
950 ObligationCauseCode
::StructInitializerSized
=> {
951 err
.note("structs must have a statically known size to be initialized");
953 ObligationCauseCode
::FieldSized
=> {
954 err
.note("only the last field of a struct may have a dynamically sized type");
956 ObligationCauseCode
::ConstSized
=> {
957 err
.note("constant expressions must have a statically known size");
959 ObligationCauseCode
::SharedStatic
=> {
960 err
.note("shared static variables must have a type that implements `Sync`");
962 ObligationCauseCode
::BuiltinDerivedObligation(ref data
) => {
963 let parent_trait_ref
= self.resolve_type_vars_if_possible(&data
.parent_trait_ref
);
964 err
.note(&format
!("required because it appears within the type `{}`",
965 parent_trait_ref
.0.self_ty()));
966 let parent_predicate
= parent_trait_ref
.to_predicate();
967 self.note_obligation_cause_code(err
,
971 ObligationCauseCode
::ImplDerivedObligation(ref data
) => {
972 let parent_trait_ref
= self.resolve_type_vars_if_possible(&data
.parent_trait_ref
);
974 &format
!("required because of the requirements on the impl of `{}` for `{}`",
976 parent_trait_ref
.0.self_ty()));
977 let parent_predicate
= parent_trait_ref
.to_predicate();
978 self.note_obligation_cause_code(err
,
982 ObligationCauseCode
::CompareImplMethodObligation { .. }
=> {
984 &format
!("the requirement `{}` appears on the impl method \
985 but not on the corresponding trait method",
991 fn suggest_new_overflow_limit(&self, err
: &mut DiagnosticBuilder
) {
992 let current_limit
= self.tcx
.sess
.recursion_limit
.get();
993 let suggested_limit
= current_limit
* 2;
995 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",