obligation: &PredicateObligation<'tcx>,
error: &MismatchedProjectionTypes<'tcx>,
) {
- let predicate =
- self.resolve_vars_if_possible(&obligation.predicate);
+ let predicate = self.resolve_vars_if_possible(&obligation.predicate);
if predicate.references_error() {
return
&mut obligations
);
if let Err(error) = self.at(&obligation.cause, obligation.param_env)
- .eq(normalized_ty, data.ty) {
+ .eq(normalized_ty, data.ty)
+ {
values = Some(infer::ValuePairs::Types(ExpectedFound {
expected: normalized_ty,
found: data.ty,
}
let msg = format!("type mismatch resolving `{}`", predicate);
- let error_id = (DiagnosticMessageId::ErrorId(271),
- Some(obligation.cause.span), msg);
+ let error_id = (
+ DiagnosticMessageId::ErrorId(271),
+ Some(obligation.cause.span),
+ msg,
+ );
let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
if fresh {
let mut diag = struct_span_err!(
- self.tcx.sess, obligation.cause.span, E0271,
- "type mismatch resolving `{}`", predicate
+ self.tcx.sess,
+ obligation.cause.span,
+ E0271,
+ "type mismatch resolving `{}`",
+ predicate
);
self.note_type_err(&mut diag, &obligation.cause, None, values, err);
self.note_obligation_cause(&mut diag, obligation);
},
GenericParamDefKind::Lifetime => continue,
};
- let name = param.name.as_symbol();
+ let name = param.name;
flags.push((name, Some(value)));
}
/// whose result could not be truly determined and thus we can't say
/// if the program type checks or not -- and they are unusual
/// occurrences in any case.
- pub fn report_overflow_error<T>(&self,
- obligation: &Obligation<'tcx, T>,
- suggest_increasing_limit: bool) -> !
+ pub fn report_overflow_error<T>(
+ &self,
+ obligation: &Obligation<'tcx, T>,
+ suggest_increasing_limit: bool,
+ ) -> !
where T: fmt::Display + TypeFoldable<'tcx>
{
let predicate =
self.resolve_vars_if_possible(&obligation.predicate);
- let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
- "overflow evaluating the requirement `{}`",
- predicate);
+ let mut err = struct_span_err!(
+ self.tcx.sess,
+ obligation.cause.span,
+ E0275,
+ "overflow evaluating the requirement `{}`",
+ predicate
+ );
if suggest_increasing_limit {
self.suggest_new_overflow_limit(&mut err);
}
- self.note_obligation_cause_code(&mut err, &obligation.predicate, &obligation.cause.code,
- &mut vec![]);
+ self.note_obligation_cause_code(
+ &mut err,
+ &obligation.predicate,
+ &obligation.cause.code,
+ &mut vec![],
+ );
err.emit();
self.tcx.sess.abort_if_errors();
ty::Predicate::ObjectSafe(trait_def_id) => {
let violations = self.tcx.object_safety_violations(trait_def_id);
- if let Some(err) = self.tcx.report_object_safety_error(
+ self.tcx.report_object_safety_error(
span,
trait_def_id,
violations,
- ) {
- err
- } else {
- return;
- }
+ )
}
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
TraitNotObjectSafe(did) => {
let violations = self.tcx.object_safety_violations(did);
- if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) {
- err
- } else {
- return;
- }
+ self.tcx.report_object_safety_error(span, did, violations)
}
// already reported in the query
trait_ref: &ty::PolyTraitRef<'_>,
body_id: hir::HirId,
) {
- let (param_ty, projection) = match &trait_ref.self_ty().kind {
- ty::Param(param_ty) => (Some(param_ty), None),
- ty::Projection(projection) => (None, Some(projection)),
+ let self_ty = trait_ref.self_ty();
+ let (param_ty, projection) = match &self_ty.kind {
+ ty::Param(_) => (true, None),
+ ty::Projection(projection) => (false, Some(projection)),
_ => return,
};
let mut suggest_restriction = |generics: &hir::Generics, msg| {
- err.span_suggestion(
- generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi(),
- &format!("consider further restricting {}", msg),
- format!(
- "{} {} ",
- if !generics.where_clause.predicates.is_empty() {
- ","
- } else {
- " where"
- },
- trait_ref.to_predicate(),
- ),
- Applicability::MachineApplicable,
- );
+ let span = generics.where_clause.span_for_predicates_or_empty_place();
+ if !span.from_expansion() && span.desugaring_kind().is_none() {
+ err.span_suggestion(
+ generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi(),
+ &format!("consider further restricting {}", msg),
+ format!(
+ "{} {} ",
+ if !generics.where_clause.predicates.is_empty() {
+ ","
+ } else {
+ " where"
+ },
+ trait_ref.to_predicate(),
+ ),
+ Applicability::MachineApplicable,
+ );
+ }
};
// FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
let mut hir_id = body_id;
while let Some(node) = self.tcx.hir().find(hir_id) {
match node {
- hir::Node::Item(hir::Item {
- kind: hir::ItemKind::Fn(_, _, generics, _), ..
- }) |
hir::Node::TraitItem(hir::TraitItem {
generics,
kind: hir::TraitItemKind::Method(..), ..
- }) |
- hir::Node::ImplItem(hir::ImplItem {
- generics,
- kind: hir::ImplItemKind::Method(..), ..
- }) if param_ty.map_or(false, |p| p.name.as_str() == "Self") => {
+ }) if param_ty && self_ty == self.tcx.types.self_param => {
// Restricting `Self` for a single method.
suggest_restriction(&generics, "`Self`");
return;
}) |
hir::Node::TraitItem(hir::TraitItem { generics, span, .. }) |
hir::Node::ImplItem(hir::ImplItem { generics, span, .. })
- if param_ty.is_some() => {
+ if param_ty => {
// Missing generic type parameter bound.
let restrict_msg = "consider further restricting this bound";
- let param_name = param_ty.unwrap().name.as_str();
+ let param_name = self_ty.to_string();
for param in generics.params.iter().filter(|p| {
- param_name == p.name.ident().as_str()
+ ¶m_name == std::convert::AsRef::<str>::as_ref(&p.name.ident().as_str())
}) {
if param_name.starts_with("impl ") {
- // `impl Trait` in argument:
+ // `impl Trait` in argument:
// `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
err.span_suggestion(
param.span,
format!("{} + {}", param.name.ident(), trait_ref),
Applicability::MachineApplicable,
);
- } else {
- if generics.where_clause.predicates.is_empty() &&
+ } else if generics.where_clause.predicates.is_empty() &&
param.bounds.is_empty()
- {
- // If there are no bounds whatsoever, suggest adding a constraint
- // to the type parameter:
- // `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
- err.span_suggestion(
- param.span,
- "consider restricting this bound",
- format!("{}", trait_ref.to_predicate()),
- Applicability::MachineApplicable,
- );
- } else if !generics.where_clause.predicates.is_empty() {
- // There is a `where` clause, so suggest expanding it:
- // `fn foo<T>(t: T) where T: Debug {}` →
- // `fn foo<T(t: T) where T: Debug, Trait {}`
- err.span_suggestion(
- generics.where_clause.span().unwrap().shrink_to_hi(),
- &format!(
- "consider further restricting type parameter `{}`",
- param_name,
- ),
- format!(", {}", trait_ref.to_predicate()),
- Applicability::MachineApplicable,
- );
+ {
+ // If there are no bounds whatsoever, suggest adding a constraint
+ // to the type parameter:
+ // `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
+ err.span_suggestion(
+ param.span,
+ "consider restricting this bound",
+ format!("{}", trait_ref.to_predicate()),
+ Applicability::MachineApplicable,
+ );
+ } else if !generics.where_clause.predicates.is_empty() {
+ // There is a `where` clause, so suggest expanding it:
+ // `fn foo<T>(t: T) where T: Debug {}` →
+ // `fn foo<T>(t: T) where T: Debug, T: Trait {}`
+ err.span_suggestion(
+ generics.where_clause.span().unwrap().shrink_to_hi(),
+ &format!(
+ "consider further restricting type parameter `{}`",
+ param_name,
+ ),
+ format!(", {}", trait_ref.to_predicate()),
+ Applicability::MachineApplicable,
+ );
+ } else {
+ // If there is no `where` clause lean towards constraining to the
+ // type parameter:
+ // `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
+ // `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
+ let sp = param.span.with_hi(span.hi());
+ let span = self.tcx.sess.source_map()
+ .span_through_char(sp, ':');
+ if sp != param.span && sp != span {
+ // Only suggest if we have high certainty that the span
+ // covers the colon in `foo<T: Trait>`.
+ err.span_suggestion(span, restrict_msg, format!(
+ "{} + ",
+ trait_ref.to_predicate(),
+ ), Applicability::MachineApplicable);
} else {
- // If there is no `where` clause lean towards constraining to the
- // type parameter:
- // `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
- // `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
- let sp = param.span.with_hi(span.hi());
- let span = self.tcx.sess.source_map()
- .span_through_char(sp, ':');
- if sp != param.span && sp != span {
- // Only suggest if we have high certainty that the span
- // covers the colon in `foo<T: Trait>`.
- err.span_suggestion(span, restrict_msg, format!(
- "{} + ",
- trait_ref.to_predicate(),
- ), Applicability::MachineApplicable);
- } else {
- err.span_label(param.span, &format!(
- "consider adding a `where {}` bound",
- trait_ref.to_predicate(),
- ));
- }
+ err.span_label(param.span, &format!(
+ "consider adding a `where {}` bound",
+ trait_ref.to_predicate(),
+ ));
}
}
return;
span: Span,
trait_def_id: DefId,
violations: Vec<ObjectSafetyViolation>,
- ) -> Option<DiagnosticBuilder<'tcx>> {
- if self.sess.trait_methods_not_found.borrow().contains(&span) {
- // Avoid emitting error caused by non-existing method (#58734)
- return None;
- }
+ ) -> DiagnosticBuilder<'tcx> {
let trait_str = self.def_path_str(trait_def_id);
let span = self.sess.source_map().def_span(span);
let mut err = struct_span_err!(
};
}
}
- Some(err)
+
+ if self.sess.trait_methods_not_found.borrow().contains(&span) {
+ // Avoid emitting error caused by non-existing method (#58734)
+ err.cancel();
+ }
+
+ err
}
}
err.note(&format!("required for the cast to the object type `{}`",
self.ty_to_string(object_ty)));
}
+ ObligationCauseCode::Coercion { source: _, target } => {
+ err.note(&format!("required by cast to type `{}`",
+ self.ty_to_string(target)));
+ }
ObligationCauseCode::RepeatVec => {
err.note("the `Copy` trait is required because the \
repeated element will be copied");
);
}
}
+ ObligationCauseCode::AssocTypeBound(impl_span, orig) => {
+ err.span_label(orig, "associated type defined here");
+ if let Some(sp) = impl_span {
+ err.span_label(sp, "in this `impl` item");
+ }
+ }
}
}