1
Fork 0

Auto merge of #100654 - compiler-errors:rework-point-at-arg, r=estebank

Rework "point at arg" suggestions to be more accurate

Fixes #100560

Introduce a new set of `ObligationCauseCode`s which have additional bookeeping for what expression caused the obligation, and which predicate caused the obligation. This allows us to look at the _unsubstituted_ signature to find out which parameter or generic type argument caused an obligaton to fail.

This means that (in most cases) we significantly improve the likelihood of pointing out the right argument that causes a fulfillment error. Also, since this logic isn't happening in just the `select_where_possible_and_mutate_fulfillment()` calls in the argument checking code, but instead during all trait selection in `FnCtxt`, we are also able to point out the correct argument even if inference means that we don't know whether an obligation has failed until well after a call expression has been checked.

r? `@ghost`
This commit is contained in:
bors 2022-08-21 21:52:56 +00:00
commit 0b71ffca18
161 changed files with 1379 additions and 790 deletions

View file

@ -740,12 +740,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err.help("...or use `match` instead of `let...else`"); err.help("...or use `match` instead of `let...else`");
} }
_ => { _ => {
if let ObligationCauseCode::BindingObligation(_, binding_span) = if let ObligationCauseCode::BindingObligation(_, span)
cause.code().peel_derives() | ObligationCauseCode::ExprBindingObligation(_, span, ..)
= cause.code().peel_derives()
&& let TypeError::RegionsPlaceholderMismatch = terr
{ {
if matches!(terr, TypeError::RegionsPlaceholderMismatch) { err.span_note(*span, "the lifetime requirement is introduced here");
err.span_note(*binding_span, "the lifetime requirement is introduced here");
}
} }
} }
} }

View file

@ -35,7 +35,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else {
return None; return None;
}; };
let ObligationCauseCode::BindingObligation(_def_id, binding_span) = *parent.code() else { let (ObligationCauseCode::BindingObligation(_, binding_span) | ObligationCauseCode::ExprBindingObligation(_, binding_span, ..))
= *parent.code() else {
return None; return None;
}; };
let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type"); let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type");

View file

@ -211,7 +211,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
); );
let mut err = self.tcx().sess.struct_span_err(span, &msg); let mut err = self.tcx().sess.struct_span_err(span, &msg);
let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = *cause.code() { let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id)
| ObligationCauseCode::ExprItemObligation(def_id, ..) =
*cause.code()
{
err.span_label(span, "doesn't satisfy where-clause"); err.span_label(span, "doesn't satisfy where-clause");
err.span_label( err.span_label(
self.tcx().def_span(def_id), self.tcx().def_span(def_id),

View file

@ -232,7 +232,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), ObligationCauseCode::MatchImpl(parent, ..) => parent.code(),
_ => cause.code(), _ => cause.code(),
} }
&& let (&ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code) && let (&ObligationCauseCode::ItemObligation(item_def_id) | &ObligationCauseCode::ExprItemObligation(item_def_id, ..), None) = (code, override_error_code)
{ {
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
// lifetime as above, but called using a fully-qualified path to the method: // lifetime as above, but called using a fully-qualified path to the method:

View file

@ -390,10 +390,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if matches!( if matches!(
&trace.cause.code().peel_derives(), &trace.cause.code().peel_derives(),
ObligationCauseCode::BindingObligation(..) ObligationCauseCode::BindingObligation(..)
| ObligationCauseCode::ExprBindingObligation(..)
) => ) =>
{ {
// Hack to get around the borrow checker because trace.cause has an `Rc`. // Hack to get around the borrow checker because trace.cause has an `Rc`.
if let ObligationCauseCode::BindingObligation(_, span) = if let ObligationCauseCode::BindingObligation(_, span)
| ObligationCauseCode::ExprBindingObligation(_, span, ..) =
&trace.cause.code().peel_derives() &trace.cause.code().peel_derives()
{ {
let span = *span; let span = *span;

View file

@ -97,7 +97,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
cause.span, cause.span,
sup_type, sup_type,
match cause.code().peel_derives() { match cause.code().peel_derives() {
ObligationCauseCode::BindingObligation(_, span) => Some(*span), ObligationCauseCode::BindingObligation(_, span)
| ObligationCauseCode::ExprBindingObligation(_, span, ..) => Some(*span),
_ => None, _ => None,
}, },
) )

View file

@ -234,13 +234,23 @@ pub enum ObligationCauseCode<'tcx> {
/// This is the trait reference from the given projection. /// This is the trait reference from the given projection.
ProjectionWf(ty::ProjectionTy<'tcx>), ProjectionWf(ty::ProjectionTy<'tcx>),
/// In an impl of trait `X` for type `Y`, type `Y` must /// Must satisfy all of the where-clause predicates of the
/// also implement all supertraits of `X`. /// given item.
ItemObligation(DefId), ItemObligation(DefId),
/// Like `ItemObligation`, but with extra detail on the source of the obligation. /// Like `ItemObligation`, but carries the span of the
/// predicate when it can be identified.
BindingObligation(DefId, Span), BindingObligation(DefId, Span),
/// Like `ItemObligation`, but carries the `HirId` of the
/// expression that caused the obligation, and the `usize`
/// indicates exactly which predicate it is in the list of
/// instantiated predicates.
ExprItemObligation(DefId, rustc_hir::HirId, usize),
/// Combines `ExprItemObligation` and `BindingObligation`.
ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize),
/// A type like `&'a T` is WF only if `T: 'a`. /// A type like `&'a T` is WF only if `T: 'a`.
ReferenceOutlivesReferent(Ty<'tcx>), ReferenceOutlivesReferent(Ty<'tcx>),

View file

@ -122,6 +122,21 @@ pub struct Generics {
} }
impl<'tcx> Generics { impl<'tcx> Generics {
/// Looks through the generics and all parents to find the index of the
/// given param def-id. This is in comparison to the `param_def_id_to_index`
/// struct member, which only stores information about this item's own
/// generics.
pub fn param_def_id_to_index(&self, tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<u32> {
if let Some(idx) = self.param_def_id_to_index.get(&def_id) {
Some(*idx)
} else if let Some(parent) = self.parent {
let parent = tcx.generics_of(parent);
parent.param_def_id_to_index(tcx, def_id)
} else {
None
}
}
#[inline] #[inline]
pub fn count(&self) -> usize { pub fn count(&self) -> usize {
self.parent_count + self.params.len() self.parent_count + self.params.len()

View file

@ -664,6 +664,16 @@ impl Span {
Some(self) Some(self)
} }
/// Like `find_ancestor_inside`, but specifically for when spans might not
/// overlaps. Take care when using this, and prefer `find_ancestor_inside`
/// when you know that the spans are nested (modulo macro expansion).
pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option<Span> {
while !Span::eq_ctxt(self, other) {
self = self.parent_callsite()?;
}
Some(self)
}
/// Edition of the crate from which this span came. /// Edition of the crate from which this span came.
pub fn edition(self) -> edition::Edition { pub fn edition(self) -> edition::Edition {
self.ctxt().edition() self.ctxt().edition()

View file

@ -860,8 +860,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
} }
} }
err.emit(); err
return;
} }
ty::PredicateKind::WellFormed(ty) => { ty::PredicateKind::WellFormed(ty) => {
@ -1564,6 +1563,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code().peel_derives(), obligation.cause.code().peel_derives(),
ObligationCauseCode::ItemObligation(_) ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ExprItemObligation(..)
| ObligationCauseCode::ExprBindingObligation(..)
| ObligationCauseCode::ObjectCastObligation(..) | ObligationCauseCode::ObjectCastObligation(..)
| ObligationCauseCode::OpaqueType | ObligationCauseCode::OpaqueType
); );
@ -2091,13 +2092,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
} }
} }
if let ObligationCauseCode::ItemObligation(def_id) = *obligation.cause.code() { if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
} else if let ( } else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span)
Ok(ref snippet), && let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..)
&ObligationCauseCode::BindingObligation(def_id, _), = *obligation.cause.code()
) =
(self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code())
{ {
let generics = self.tcx.generics_of(def_id); let generics = self.tcx.generics_of(def_id);
if generics.params.iter().any(|p| p.name != kw::SelfUpper) if generics.params.iter().any(|p| p.name != kw::SelfUpper)
@ -2520,15 +2519,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
err: &mut Diagnostic, err: &mut Diagnostic,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) { ) {
let ( let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
ty::PredicateKind::Trait(pred), let (ObligationCauseCode::BindingObligation(item_def_id, span)
&ObligationCauseCode::BindingObligation(item_def_id, span), | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
) = ( = *obligation.cause.code().peel_derives() else { return; };
obligation.predicate.kind().skip_binder(),
obligation.cause.code().peel_derives(),
) else {
return;
};
debug!(?pred, ?item_def_id, ?span); debug!(?pred, ?item_def_id, ?span);
let (Some(node), true) = ( let (Some(node), true) = (

View file

@ -143,7 +143,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
} }
if let ObligationCauseCode::ItemObligation(item) if let ObligationCauseCode::ItemObligation(item)
| ObligationCauseCode::BindingObligation(item, _) = *obligation.cause.code() | ObligationCauseCode::BindingObligation(item, _)
| ObligationCauseCode::ExprItemObligation(item, ..)
| ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
{ {
// FIXME: maybe also have some way of handling methods // FIXME: maybe also have some way of handling methods
// from other traits? That would require name resolution, // from other traits? That would require name resolution,

View file

@ -671,11 +671,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
// It only make sense when suggesting dereferences for arguments // It only make sense when suggesting dereferences for arguments
let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code()
return false; else { return false; };
}; let Some(typeck_results) = self.in_progress_typeck_results
let param_env = obligation.param_env; else { return false; };
let body_id = obligation.cause.body_id; let typeck_results = typeck_results.borrow();
let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id)
else { return false; };
let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr)
else { return false; };
let span = obligation.cause.span; let span = obligation.cause.span;
let mut real_trait_pred = trait_pred; let mut real_trait_pred = trait_pred;
let mut code = obligation.cause.code(); let mut code = obligation.cause.code();
@ -687,9 +692,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Skipping binder here, remapping below // Skipping binder here, remapping below
let real_ty = real_trait_pred.self_ty().skip_binder(); let real_ty = real_trait_pred.self_ty().skip_binder();
if self.can_eq(obligation.param_env, real_ty, arg_ty).is_err() {
continue;
}
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span); let mut autoderef = Autoderef::new(
self,
obligation.param_env,
obligation.cause.body_id,
span,
base_ty,
span,
);
if let Some(steps) = autoderef.find_map(|(ty, steps)| { if let Some(steps) = autoderef.find_map(|(ty, steps)| {
// Re-add the `&` // Re-add the `&`
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });
@ -697,8 +712,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Remapping bound vars here // Remapping bound vars here
let real_trait_pred_and_ty = let real_trait_pred_and_ty =
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
let obligation = self let obligation = self.mk_trait_obligation_with_new_self_ty(
.mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred_and_ty); obligation.param_env,
real_trait_pred_and_ty,
);
Some(steps).filter(|_| self.predicate_may_hold(&obligation)) Some(steps).filter(|_| self.predicate_may_hold(&obligation))
}) { }) {
if steps > 0 { if steps > 0 {
@ -727,7 +744,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let real_trait_pred_and_base_ty = let real_trait_pred_and_base_ty =
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty)); real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty));
let obligation = self.mk_trait_obligation_with_new_self_ty( let obligation = self.mk_trait_obligation_with_new_self_ty(
param_env, obligation.param_env,
real_trait_pred_and_base_ty, real_trait_pred_and_base_ty,
); );
if self.predicate_may_hold(&obligation) { if self.predicate_may_hold(&obligation) {
@ -855,6 +872,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
_ => return false, _ => return false,
}; };
if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. }) if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. })
&& obligation.cause.span.can_be_used_for_suggestions()
{ {
// When the obligation error has been ensured to have been caused by // When the obligation error has been ensured to have been caused by
// an argument, the `obligation.cause.span` points at the expression // an argument, the `obligation.cause.span` points at the expression
@ -885,7 +903,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code() obligation.cause.code()
{ {
&parent_code &parent_code
} else if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() { } else if let ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
{
obligation.cause.code() obligation.cause.code()
} else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) = } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) =
span.ctxt().outer_expn_data().kind span.ctxt().outer_expn_data().kind
@ -911,35 +931,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let param_env = obligation.param_env; let param_env = obligation.param_env;
// Try to apply the original trait binding obligation by borrowing. // Try to apply the original trait binding obligation by borrowing.
let mut try_borrowing = let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
|old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool { blacklist: &[DefId]|
if blacklist.contains(&old_pred.def_id()) { -> bool {
return false; if blacklist.contains(&old_pred.def_id()) {
} return false;
// We map bounds to `&T` and `&mut T` }
let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| { // We map bounds to `&T` and `&mut T`
( let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| {
trait_pred, (
self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), trait_pred,
) self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
}); )
let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| { });
( let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| {
trait_pred, (
self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), trait_pred,
) self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
}); )
});
let mk_result = |trait_pred_and_new_ty| { let mk_result = |trait_pred_and_new_ty| {
let obligation = let obligation =
self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty); self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
self.predicate_must_hold_modulo_regions(&obligation) self.predicate_must_hold_modulo_regions(&obligation)
}; };
let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
&& let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind()
{ {
( (
@ -950,79 +971,81 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
(false, false) (false, false)
}; };
if imm_ref_self_ty_satisfies_pred if imm_ref_self_ty_satisfies_pred
|| mut_ref_self_ty_satisfies_pred || mut_ref_self_ty_satisfies_pred
|| ref_inner_ty_satisfies_pred || ref_inner_ty_satisfies_pred
{ {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
// We have a very specific type of error, where just borrowing this argument // We don't want a borrowing suggestion on the fields in structs,
// might solve the problem. In cases like this, the important part is the // ```
// original type obligation, not the last one that failed, which is arbitrary. // struct Foo {
// Because of this, we modify the error to refer to the original obligation and // the_foos: Vec<Foo>
// return early in the caller. // }
// ```
let msg = format!("the trait bound `{}` is not satisfied", old_pred); if !matches!(
if has_custom_message { span.ctxt().outer_expn_data().kind,
err.note(&msg); ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
} else { ) {
err.message = return false;
vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
}
if snippet.starts_with('&') {
// This is already a literal borrow and the obligation is failing
// somewhere else in the obligation chain. Do not suggest non-sense.
return false;
}
err.span_label(
span,
&format!(
"expected an implementor of trait `{}`",
old_pred.print_modifiers_and_trait_path(),
),
);
// This if is to prevent a special edge-case
if matches!(
span.ctxt().outer_expn_data().kind,
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
) {
// We don't want a borrowing suggestion on the fields in structs,
// ```
// struct Foo {
// the_foos: Vec<Foo>
// }
// ```
if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
err.span_suggestions(
span.shrink_to_lo(),
"consider borrowing here",
["&".to_string(), "&mut ".to_string()].into_iter(),
Applicability::MaybeIncorrect,
);
} else {
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!(
"consider{} borrowing here",
if is_mut { " mutably" } else { "" }
),
format!("&{}", if is_mut { "mut " } else { "" }),
Applicability::MaybeIncorrect,
);
}
}
return true;
} }
if snippet.starts_with('&') {
// This is already a literal borrow and the obligation is failing
// somewhere else in the obligation chain. Do not suggest non-sense.
return false;
}
// We have a very specific type of error, where just borrowing this argument
// might solve the problem. In cases like this, the important part is the
// original type obligation, not the last one that failed, which is arbitrary.
// Because of this, we modify the error to refer to the original obligation and
// return early in the caller.
let msg = format!("the trait bound `{}` is not satisfied", old_pred);
if has_custom_message {
err.note(&msg);
} else {
err.message =
vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
}
err.span_label(
span,
format!(
"the trait `{}` is not implemented for `{}`",
old_pred.print_modifiers_and_trait_path(),
old_pred.self_ty().skip_binder(),
),
);
if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
err.span_suggestions(
span.shrink_to_lo(),
"consider borrowing here",
["&".to_string(), "&mut ".to_string()].into_iter(),
Applicability::MaybeIncorrect,
);
} else {
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!(
"consider{} borrowing here",
if is_mut { " mutably" } else { "" }
),
format!("&{}", if is_mut { "mut " } else { "" }),
Applicability::MaybeIncorrect,
);
}
return true;
} }
return false; }
}; return false;
};
if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code { if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code {
try_borrowing(cause.derived.parent_trait_pred, &[]) try_borrowing(cause.derived.parent_trait_pred, &[])
} else if let ObligationCauseCode::BindingObligation(_, _) } else if let ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ItemObligation(..) = code | ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..)
| ObligationCauseCode::ExprBindingObligation(..) = code
{ {
try_borrowing(poly_trait_pred, &never_suggest_borrow) try_borrowing(poly_trait_pred, &never_suggest_borrow)
} else { } else {
@ -2244,11 +2267,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
region, object_ty, region, object_ty,
)); ));
} }
ObligationCauseCode::ItemObligation(_item_def_id) => { ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..) => {
// We hold the `DefId` of the item introducing the obligation, but displaying it // We hold the `DefId` of the item introducing the obligation, but displaying it
// doesn't add user usable information. It always point at an associated item. // doesn't add user usable information. It always point at an associated item.
} }
ObligationCauseCode::BindingObligation(item_def_id, span) => { ObligationCauseCode::BindingObligation(item_def_id, span)
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => {
let item_name = tcx.def_path_str(item_def_id); let item_name = tcx.def_path_str(item_def_id);
let mut multispan = MultiSpan::from(span); let mut multispan = MultiSpan::from(span);
if let Some(ident) = tcx.opt_item_ident(item_def_id) { if let Some(ident) = tcx.opt_item_ident(item_def_id) {

View file

@ -117,11 +117,21 @@ pub enum TraitQueryMode {
/// Creates predicate obligations from the generic bounds. /// Creates predicate obligations from the generic bounds.
pub fn predicates_for_generics<'tcx>( pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>, cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
generic_bounds: ty::InstantiatedPredicates<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> { ) -> impl Iterator<Item = PredicateObligation<'tcx>> {
util::predicates_for_generics(cause, 0, param_env, generic_bounds) let generic_bounds = generic_bounds;
debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map(
move |(idx, (predicate, span))| Obligation {
cause: cause(idx, span),
recursion_depth: 0,
param_env: param_env,
predicate,
},
)
} }
/// Determines whether the type `ty` is known to meet `bound` and /// Determines whether the type `ty` is known to meet `bound` and

View file

@ -11,8 +11,6 @@ use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable
use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
pub use rustc_infer::traits::{self, util::*}; pub use rustc_infer::traits::{self, util::*};
use std::iter;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// `TraitAliasExpander` iterator // `TraitAliasExpander` iterator
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -210,7 +208,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
let Normalized { value: predicates, obligations: normalization_obligations2 } = let Normalized { value: predicates, obligations: normalization_obligations2 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), predicates); super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
let impl_obligations = let impl_obligations =
predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates); super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);
let impl_obligations = impl_obligations let impl_obligations = impl_obligations
.chain(normalization_obligations1.into_iter()) .chain(normalization_obligations1.into_iter())
@ -219,27 +217,6 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
(subject, impl_obligations) (subject, impl_obligations)
} }
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
iter::zip(generic_bounds.predicates, generic_bounds.spans).map(move |(predicate, span)| {
let cause = match *cause.code() {
traits::ItemObligation(def_id) if !span.is_dummy() => traits::ObligationCause::new(
cause.span,
cause.body_id,
traits::BindingObligation(def_id, span),
),
_ => cause.clone(),
};
Obligation { cause, recursion_depth, param_env, predicate }
})
}
pub fn predicate_for_trait_ref<'tcx>( pub fn predicate_for_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,

View file

@ -711,7 +711,7 @@ impl<'tcx> WfPredicates<'tcx> {
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
.map(|((mut pred, span), origin_def_id)| { .map(|((mut pred, span), origin_def_id)| {
let code = if span.is_dummy() { let code = if span.is_dummy() {
traits::MiscObligation traits::ItemObligation(origin_def_id)
} else { } else {
traits::BindingObligation(origin_def_id, span) traits::BindingObligation(origin_def_id, span)
}; };

View file

@ -1463,7 +1463,7 @@ pub fn check_type_bounds<'tcx>(
); );
let mk_cause = |span: Span| { let mk_cause = |span: Span| {
let code = if span.is_dummy() { let code = if span.is_dummy() {
traits::MiscObligation traits::ItemObligation(trait_ty.def_id)
} else { } else {
traits::BindingObligation(trait_ty.def_id, span) traits::BindingObligation(trait_ty.def_id, span)
}; };

View file

@ -607,9 +607,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
pub(in super::super) fn select_all_obligations_or_error(&self) { pub(in super::super) fn select_all_obligations_or_error(&self) {
let errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self); let mut errors = self.fulfillment_cx.borrow_mut().select_all_or_error(&self);
if !errors.is_empty() { if !errors.is_empty() {
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
self.report_fulfillment_errors(&errors, self.inh.body_id, false); self.report_fulfillment_errors(&errors, self.inh.body_id, false);
} }
} }
@ -623,6 +624,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self); let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
if !result.is_empty() { if !result.is_empty() {
mutate_fulfillment_errors(&mut result); mutate_fulfillment_errors(&mut result);
self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred); self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred);
} }
} }
@ -820,23 +822,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = item_ty.subst(self.tcx, substs); let ty = item_ty.subst(self.tcx, substs);
self.write_resolution(hir_id, Ok((def_kind, def_id))); self.write_resolution(hir_id, Ok((def_kind, def_id)));
self.add_required_obligations_with_code(
span, let code = match lang_item {
def_id, hir::LangItem::IntoFutureIntoFuture => {
&substs, Some(ObligationCauseCode::AwaitableExpr(expr_hir_id))
match lang_item { }
hir::LangItem::IntoFutureIntoFuture => { hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
ObligationCauseCode::AwaitableExpr(expr_hir_id) Some(ObligationCauseCode::ForLoopIterator)
} }
hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => { hir::LangItem::TryTraitFromOutput
ObligationCauseCode::ForLoopIterator | hir::LangItem::TryTraitFromResidual
} | hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark),
hir::LangItem::TryTraitFromOutput _ => None,
| hir::LangItem::TryTraitFromResidual };
| hir::LangItem::TryTraitBranch => ObligationCauseCode::QuestionMark, if let Some(code) = code {
_ => traits::ItemObligation(def_id), self.add_required_obligations_with_code(span, def_id, substs, move |_, _| code.clone());
}, } else {
); self.add_required_obligations_for_hir(span, def_id, substs, hir_id);
}
(Res::Def(def_kind, def_id), ty) (Res::Def(def_kind, def_id), ty)
} }
@ -1348,7 +1352,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// First, store the "user substs" for later. // First, store the "user substs" for later.
self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty); self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
self.add_required_obligations(span, def_id, &substs); self.add_required_obligations_for_hir(span, def_id, &substs, hir_id);
// Substitute the values for the type parameters into the type of // Substitute the values for the type parameters into the type of
// the referenced item. // the referenced item.
@ -1385,32 +1389,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
/// Add all the obligations that are required, substituting and normalized appropriately. /// Add all the obligations that are required, substituting and normalized appropriately.
pub(crate) fn add_required_obligations( pub(crate) fn add_required_obligations_for_hir(
&self, &self,
span: Span, span: Span,
def_id: DefId, def_id: DefId,
substs: &SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
hir_id: hir::HirId,
) { ) {
self.add_required_obligations_with_code( self.add_required_obligations_with_code(span, def_id, substs, |idx, span| {
span, if span.is_dummy() {
def_id, ObligationCauseCode::ExprItemObligation(def_id, hir_id, idx)
substs, } else {
traits::ItemObligation(def_id), ObligationCauseCode::ExprBindingObligation(def_id, span, hir_id, idx)
) }
})
} }
#[tracing::instrument(level = "debug", skip(self, span, def_id, substs))] #[tracing::instrument(level = "debug", skip(self, code, span, def_id, substs))]
fn add_required_obligations_with_code( fn add_required_obligations_with_code(
&self, &self,
span: Span, span: Span,
def_id: DefId, def_id: DefId,
substs: &SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
code: ObligationCauseCode<'tcx>, code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
) { ) {
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs); let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
for obligation in traits::predicates_for_generics( for obligation in traits::predicates_for_generics(
traits::ObligationCause::new(span, self.body_id, code), |idx, predicate_span| {
traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
},
self.param_env, self.param_env,
bounds, bounds,
) { ) {

View file

@ -15,6 +15,7 @@ use crate::check::{
use crate::structured_errors::StructuredDiagnostic; use crate::structured_errors::StructuredDiagnostic;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan}; use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def::{CtorOf, DefKind, Res};
@ -27,13 +28,14 @@ use rustc_infer::infer::InferOk;
use rustc_infer::infer::TypeTrace; use rustc_infer::infer::TypeTrace;
use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty}; use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::{self, Span}; use rustc_span::{self, Span};
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext}; use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
use std::iter; use std::iter;
use std::ops::ControlFlow;
use std::slice; use std::slice;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@ -247,17 +249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Cause selection errors caused by resolving a single argument to point at the // Cause selection errors caused by resolving a single argument to point at the
// argument and not the call. This lets us customize the span pointed to in the // argument and not the call. This lets us customize the span pointed to in the
// fulfillment error to be more accurate. // fulfillment error to be more accurate.
let coerced_ty = let coerced_ty = self.resolve_vars_with_obligations(coerced_ty);
self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| {
self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
self.point_at_arg_instead_of_call_if_possible(
errors,
call_expr,
call_span,
provided_args,
&expected_input_tys,
);
});
let coerce_error = self let coerce_error = self
.try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None) .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
@ -312,16 +304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// an "opportunistic" trait resolution of any trait bounds on // an "opportunistic" trait resolution of any trait bounds on
// the call. This helps coercions. // the call. This helps coercions.
if check_closures { if check_closures {
self.select_obligations_where_possible(false, |errors| { self.select_obligations_where_possible(false, |_| {})
self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
self.point_at_arg_instead_of_call_if_possible(
errors,
call_expr,
call_span,
&provided_args,
&expected_input_tys,
);
})
} }
// Check each argument, to satisfy the input it was provided for // Check each argument, to satisfy the input it was provided for
@ -674,7 +657,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
}; };
self.label_fn_like(&mut err, fn_def_id, callee_ty, Some(mismatch_idx), is_method); self.label_fn_like(
&mut err,
fn_def_id,
callee_ty,
Some(mismatch_idx),
is_method,
);
err.emit(); err.emit();
return; return;
} }
@ -1081,8 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
let suggestion_text = if let Some(provided_idx) = provided_idx let suggestion_text = if let Some(provided_idx) = provided_idx
&& let (_, provided_span) = provided_arg_tys[*provided_idx] && let (_, provided_span) = provided_arg_tys[*provided_idx]
&& let Ok(arg_text) = && let Ok(arg_text) = source_map.span_to_snippet(provided_span)
source_map.span_to_snippet(provided_span)
{ {
arg_text arg_text
} else { } else {
@ -1183,7 +1171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.write_user_type_annotation_from_substs(hir_id, did, substs, None); self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
// Check bounds on type arguments used in the path. // Check bounds on type arguments used in the path.
self.add_required_obligations(path_span, did, substs); self.add_required_obligations_for_hir(path_span, did, substs, hir_id);
Some((variant, ty)) Some((variant, ty))
} else { } else {
@ -1620,183 +1608,406 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
/// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk /// Given a vector of fulfillment errors, try to adjust the spans of the
/// the checked and coerced types for each argument to see if any of the `FulfillmentError`s /// errors to more accurately point at the cause of the failure.
/// reference a type argument. The reason to walk also the checked type is that the coerced type ///
/// can be not easily comparable with predicate type (because of coercion). If the types match /// This applies to calls, methods, and struct expressions. This will also
/// for either checked or coerced type, and there's only *one* argument that does, we point at /// try to deduplicate errors that are due to the same cause but might
/// the corresponding argument's expression span instead of the `fn` call path span. /// have been created with different [`ObligationCause`][traits::ObligationCause]s.
fn point_at_arg_instead_of_call_if_possible( pub(super) fn adjust_fulfillment_errors_for_expr_obligation(
&self, &self,
errors: &mut Vec<traits::FulfillmentError<'tcx>>, errors: &mut Vec<traits::FulfillmentError<'tcx>>,
expr: &'tcx hir::Expr<'tcx>,
call_sp: Span,
args: &'tcx [hir::Expr<'tcx>],
expected_tys: &[Ty<'tcx>],
) { ) {
// We *do not* do this for desugared call spans to keep good diagnostics when involving // Store a mapping from `(Span, Predicate) -> ObligationCause`, so that
// the `?` operator. // other errors that have the same span and predicate can also get fixed,
if call_sp.desugaring_kind().is_some() { // even if their `ObligationCauseCode` isn't an `Expr*Obligation` kind.
return; // This is important since if we adjust one span but not the other, then
// we will have "duplicated" the error on the UI side.
let mut remap_cause = FxHashSet::default();
let mut not_adjusted = vec![];
for error in errors {
let before_span = error.obligation.cause.span;
if self.adjust_fulfillment_error_for_expr_obligation(error)
|| before_span != error.obligation.cause.span
{
// Store both the predicate and the predicate *without constness*
// since sometimes we instantiate and check both of these in a
// method call, for example.
remap_cause.insert((
before_span,
error.obligation.predicate,
error.obligation.cause.clone(),
));
remap_cause.insert((
before_span,
error.obligation.predicate.without_const(self.tcx),
error.obligation.cause.clone(),
));
} else {
// If it failed to be adjusted once around, it may be adjusted
// via the "remap cause" mapping the second time...
not_adjusted.push(error);
}
} }
'outer: for error in errors { for error in not_adjusted {
// Only if the cause is somewhere inside the expression we want try to point at arg. for (span, predicate, cause) in &remap_cause {
// Otherwise, it means that the cause is somewhere else and we should not change if *predicate == error.obligation.predicate
// anything because we can break the correct span. && span.contains(error.obligation.cause.span)
if !call_sp.contains(error.obligation.cause.span) { {
continue; error.obligation.cause = cause.clone();
}
// Peel derived obligation, because it's the type that originally
// started this inference chain that matters, not the one we wound
// up with at the end.
fn unpeel_to_top<'a, 'tcx>(
mut code: &'a ObligationCauseCode<'tcx>,
) -> &'a ObligationCauseCode<'tcx> {
let mut result_code = code;
loop {
let parent = match code {
ObligationCauseCode::ImplDerivedObligation(c) => &c.derived.parent_code,
ObligationCauseCode::BuiltinDerivedObligation(c)
| ObligationCauseCode::DerivedObligation(c) => &c.parent_code,
_ => break result_code,
};
(result_code, code) = (code, parent);
}
}
let self_: ty::subst::GenericArg<'_> =
match unpeel_to_top(error.obligation.cause.code()) {
ObligationCauseCode::BuiltinDerivedObligation(code)
| ObligationCauseCode::DerivedObligation(code) => {
code.parent_trait_pred.self_ty().skip_binder().into()
}
ObligationCauseCode::ImplDerivedObligation(code) => {
code.derived.parent_trait_pred.self_ty().skip_binder().into()
}
_ => match error.obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(predicate) => predicate.self_ty().into(),
ty::PredicateKind::Projection(predicate) => {
predicate.projection_ty.self_ty().into()
}
_ => continue,
},
};
let self_ = self.resolve_vars_if_possible(self_);
let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_);
let typeck_results = self.typeck_results.borrow();
for (idx, arg) in args.iter().enumerate() {
// Don't adjust the span if we already have a more precise span
// within one of the args.
if arg.span.contains(error.obligation.cause.span) {
let references_arg =
typeck_results.expr_ty_opt(arg).map_or(false, &ty_matches_self)
|| expected_tys.get(idx).copied().map_or(false, &ty_matches_self);
if references_arg && !arg.span.from_expansion() {
error.obligation.cause.map_code(|parent_code| {
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: args[idx].hir_id,
call_hir_id: expr.hir_id,
parent_code,
}
})
}
continue 'outer;
}
}
// Collect the argument position for all arguments that could have caused this
// `FulfillmentError`.
let mut referenced_in: Vec<_> = std::iter::zip(expected_tys, args)
.enumerate()
.flat_map(|(idx, (expected_ty, arg))| {
if let Some(arg_ty) = typeck_results.expr_ty_opt(arg) {
vec![(idx, arg_ty), (idx, *expected_ty)]
} else {
vec![]
}
})
.filter_map(|(i, ty)| {
let ty = self.resolve_vars_if_possible(ty);
// We walk the argument type because the argument's type could have
// been `Option<T>`, but the `FulfillmentError` references `T`.
if ty_matches_self(ty) { Some(i) } else { None }
})
.collect();
// Both checked and coerced types could have matched, thus we need to remove
// duplicates.
// We sort primitive type usize here and can use unstable sort
referenced_in.sort_unstable();
referenced_in.dedup();
if let &[idx] = &referenced_in[..] {
// Do not point at the inside of a macro.
// That would often result in poor error messages.
if args[idx].span.from_expansion() {
continue; continue;
} }
// We make sure that only *one* argument matches the obligation failure
// and we assign the obligation's span to its expression's.
error.obligation.cause.span = args[idx].span;
error.obligation.cause.map_code(|parent_code| {
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: args[idx].hir_id,
call_hir_id: expr.hir_id,
parent_code,
}
});
} else if error.obligation.cause.span == call_sp {
// Make function calls point at the callee, not the whole thing.
if let hir::ExprKind::Call(callee, _) = expr.kind {
error.obligation.cause.span = callee.span;
}
} }
} }
} }
/// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the fn adjust_fulfillment_error_for_expr_obligation(
/// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
/// were caused by them. If they were, we point at the corresponding type argument's span
/// instead of the `fn` call path span.
fn point_at_type_arg_instead_of_call_if_possible(
&self, &self,
errors: &mut Vec<traits::FulfillmentError<'tcx>>, error: &mut traits::FulfillmentError<'tcx>,
call_expr: &'tcx hir::Expr<'tcx>, ) -> bool {
) { let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx))
if let hir::ExprKind::Call(path, _) = &call_expr.kind { = *error.obligation.cause.code().peel_derives() else { return false; };
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind { let hir = self.tcx.hir();
for error in errors { let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; };
let self_ty = match error.obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(predicate) => predicate.self_ty(), // Skip over mentioning async lang item
ty::PredicateKind::Projection(predicate) => { if Some(def_id) == self.tcx.lang_items().from_generator_fn()
predicate.projection_ty.self_ty() && error.obligation.cause.span.desugaring_kind()
} == Some(rustc_span::DesugaringKind::Async)
_ => continue, {
}; return false;
// If any of the type arguments in this path segment caused the }
// `FulfillmentError`, point at its span (#61860).
for arg in path let Some(unsubstituted_pred) =
.segments self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx)
.iter() else { return false; };
.filter_map(|seg| seg.args.as_ref())
.flat_map(|a| a.args.iter()) let generics = self.tcx.generics_of(def_id);
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
ty::PredicateKind::Trait(pred) => pred.trait_ref.substs,
ty::PredicateKind::Projection(pred) => pred.projection_ty.substs,
_ => ty::List::empty(),
};
let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| {
predicate_substs.types().find_map(|ty| {
ty.walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Param(param_ty) = ty.kind()
&& matches(param_ty)
{ {
if let hir::GenericArg::Type(hir_ty) = &arg Some(arg)
&& let Some(ty) = } else {
self.typeck_results.borrow().node_type_opt(hir_ty.hir_id) None
&& self.resolve_vars_if_possible(ty) == self_ty }
})
})
};
// Prefer generics that are local to the fn item, since these are likely
// to be the cause of the unsatisfied predicate.
let mut param_to_point_at = find_param_matching(&|param_ty| {
self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id
});
// Fall back to generic that isn't local to the fn item. This will come
// from a trait or impl, for example.
let mut fallback_param_to_point_at = find_param_matching(&|param_ty| {
self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id
&& param_ty.name != rustc_span::symbol::kw::SelfUpper
});
// Finally, the `Self` parameter is possibly the reason that the predicate
// is unsatisfied. This is less likely to be true for methods, because
// method probe means that we already kinda check that the predicates due
// to the `Self` type are true.
let mut self_param_to_point_at =
find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper);
// Finally, for ambiguity-related errors, we actually want to look
// for a parameter that is the source of the inference type left
// over in this predicate.
if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code {
fallback_param_to_point_at = None;
self_param_to_point_at = None;
param_to_point_at =
self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
}
if self.closure_span_overlaps_error(error, expr.span) {
return false;
}
match &expr.kind {
hir::ExprKind::Path(qpath) => {
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Call(callee, args),
hir_id: call_hir_id,
span: call_span,
..
}) = hir.get(hir.get_parent_node(expr.hir_id))
&& callee.hir_id == expr.hir_id
{
if self.closure_span_overlaps_error(error, *call_span) {
return false;
}
for param in
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
{
if self.point_at_arg_if_possible(
error,
def_id,
param,
*call_hir_id,
callee.span,
args,
)
{ {
error.obligation.cause.span = hir_ty.span; return true;
break;
} }
} }
// Notably, we only point to params that are local to the
// item we're checking, since those are the ones we are able
// to look in the final `hir::PathSegment` for. Everything else
// would require a deeper search into the `qpath` than I think
// is worthwhile.
if let Some(param_to_point_at) = param_to_point_at
&& self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
{
return true;
}
} }
} }
hir::ExprKind::MethodCall(segment, args, ..) => {
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
{
if self.point_at_arg_if_possible(
error,
def_id,
param,
hir_id,
segment.ident.span,
args,
) {
return true;
}
}
if let Some(param_to_point_at) = param_to_point_at
&& self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment)
{
return true;
}
}
hir::ExprKind::Struct(qpath, fields, ..) => {
if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
self.typeck_results.borrow().qpath_res(qpath, hir_id)
{
for param in
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
{
if let Some(param) = param
&& self.point_at_field_if_possible(
error,
def_id,
param,
variant_def_id,
fields,
)
{
return true;
}
}
}
if let Some(param_to_point_at) = param_to_point_at
&& self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
{
return true;
}
}
_ => {}
} }
false
}
fn closure_span_overlaps_error(
&self,
error: &traits::FulfillmentError<'tcx>,
span: Span,
) -> bool {
if let traits::FulfillmentErrorCode::CodeSelectionError(
traits::SelectionError::OutputTypeParameterMismatch(_, expected, _),
) = error.code
&& let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind()
&& span.overlaps(self.tcx.def_span(*def_id))
{
true
} else {
false
}
}
fn point_at_arg_if_possible(
&self,
error: &mut traits::FulfillmentError<'tcx>,
def_id: DefId,
param_to_point_at: ty::GenericArg<'tcx>,
call_hir_id: hir::HirId,
callee_span: Span,
args: &[hir::Expr<'tcx>],
) -> bool {
let sig = self.tcx.fn_sig(def_id).skip_binder();
let args_referencing_param: Vec<_> = sig
.inputs()
.iter()
.enumerate()
.filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at))
.collect();
// If there's one field that references the given generic, great!
if let [(idx, _)] = args_referencing_param.as_slice() && let Some(arg) = args.get(*idx) {
error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span);
error.obligation.cause.map_code(|parent_code| {
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: arg.hir_id,
call_hir_id,
parent_code,
}
});
return true;
} else if args_referencing_param.len() > 0 {
// If more than one argument applies, then point to the callee span at least...
// We have chance to fix this up further in `point_at_generics_if_possible`
error.obligation.cause.span = callee_span;
}
false
}
fn point_at_field_if_possible(
&self,
error: &mut traits::FulfillmentError<'tcx>,
def_id: DefId,
param_to_point_at: ty::GenericArg<'tcx>,
variant_def_id: DefId,
expr_fields: &[hir::ExprField<'tcx>],
) -> bool {
let def = self.tcx.adt_def(def_id);
let identity_substs = ty::InternalSubsts::identity_for_item(self.tcx, def_id);
let fields_referencing_param: Vec<_> = def
.variant_with_id(variant_def_id)
.fields
.iter()
.filter(|field| {
let field_ty = field.ty(self.tcx, identity_substs);
find_param_in_ty(field_ty, param_to_point_at)
})
.collect();
if let [field] = fields_referencing_param.as_slice() {
for expr_field in expr_fields {
// Look for the ExprField that matches the field, using the
// same rules that check_expr_struct uses for macro hygiene.
if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx)
{
error.obligation.cause.span = expr_field
.expr
.span
.find_ancestor_in_same_ctxt(error.obligation.cause.span)
.unwrap_or(expr_field.span);
return true;
}
}
}
false
}
fn point_at_path_if_possible(
&self,
error: &mut traits::FulfillmentError<'tcx>,
def_id: DefId,
param: ty::GenericArg<'tcx>,
qpath: &QPath<'tcx>,
) -> bool {
match qpath {
hir::QPath::Resolved(_, path) => {
if let Some(segment) = path.segments.last()
&& self.point_at_generic_if_possible(error, def_id, param, segment)
{
return true;
}
}
hir::QPath::TypeRelative(_, segment) => {
if self.point_at_generic_if_possible(error, def_id, param, segment) {
return true;
}
}
_ => {}
}
false
}
fn point_at_generic_if_possible(
&self,
error: &mut traits::FulfillmentError<'tcx>,
def_id: DefId,
param_to_point_at: ty::GenericArg<'tcx>,
segment: &hir::PathSegment<'tcx>,
) -> bool {
let own_substs = self
.tcx
.generics_of(def_id)
.own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
let Some((index, _)) = own_substs
.iter()
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
.enumerate()
.find(|(_, arg)| **arg == param_to_point_at) else { return false };
let Some(arg) = segment
.args()
.args
.iter()
.filter(|arg| matches!(arg, hir::GenericArg::Type(_)))
.nth(index) else { return false; };
error.obligation.cause.span = arg
.span()
.find_ancestor_in_same_ctxt(error.obligation.cause.span)
.unwrap_or(arg.span());
true
}
fn find_ambiguous_parameter_in<T: TypeVisitable<'tcx>>(
&self,
item_def_id: DefId,
t: T,
) -> Option<ty::GenericArg<'tcx>> {
struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId);
impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> {
type BreakTy = ty::GenericArg<'tcx>;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
if let Some(origin) = self.0.type_var_origin(ty)
&& let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) =
origin.kind
&& let generics = self.0.tcx.generics_of(self.1)
&& let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
&& let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1)
.get(index as usize)
{
ControlFlow::Break(*subst)
} else {
ty.super_visit_with(self)
}
}
}
t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value()
} }
fn label_fn_like( fn label_fn_like(
@ -1864,14 +2075,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let new_def_id = self.probe(|_| { let new_def_id = self.probe(|_| {
let trait_ref = ty::TraitRef::new( let trait_ref = ty::TraitRef::new(
call_kind.to_def_id(self.tcx), call_kind.to_def_id(self.tcx),
self.tcx.mk_substs([ self.tcx.mk_substs(
ty::GenericArg::from(callee_ty), [
self.next_ty_var(TypeVariableOrigin { ty::GenericArg::from(callee_ty),
kind: TypeVariableOriginKind::MiscVariable, self.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable,
}) span: rustc_span::DUMMY_SP,
.into(), })
].into_iter()), .into(),
]
.into_iter(),
),
); );
let obligation = traits::Obligation::new( let obligation = traits::Obligation::new(
traits::ObligationCause::dummy(), traits::ObligationCause::dummy(),
@ -1886,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => { Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
Some(impl_source.impl_def_id) Some(impl_source.impl_def_id)
} }
_ => None _ => None,
} }
}); });
if let Some(new_def_id) = new_def_id { if let Some(new_def_id) = new_def_id {
@ -1940,3 +2154,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
} }
fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>) -> bool {
let mut walk = ty.walk();
while let Some(arg) = walk.next() {
if arg == param_to_point_at {
return true;
} else if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(..) = ty.kind()
{
// This logic may seem a bit strange, but typically when
// we have a projection type in a function signature, the
// argument that's being passed into that signature is
// not actually constraining that projection's substs in
// a meaningful way. So we skip it, and see improvements
// in some UI tests.
walk.skip_current_subtree();
}
}
false
}

View file

@ -491,7 +491,19 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// so we just call `predicates_for_generics` directly to avoid redoing work. // so we just call `predicates_for_generics` directly to avoid redoing work.
// `self.add_required_obligations(self.span, def_id, &all_substs);` // `self.add_required_obligations(self.span, def_id, &all_substs);`
for obligation in traits::predicates_for_generics( for obligation in traits::predicates_for_generics(
traits::ObligationCause::new(self.span, self.body_id, traits::ItemObligation(def_id)), |idx, span| {
let code = if span.is_dummy() {
ObligationCauseCode::ExprItemObligation(def_id, self.call_expr.hir_id, idx)
} else {
ObligationCauseCode::ExprBindingObligation(
def_id,
span,
self.call_expr.hir_id,
idx,
)
};
traits::ObligationCause::new(self.span, self.body_id, code)
},
self.param_env, self.param_env,
method_predicates, method_predicates,
) { ) {

View file

@ -534,7 +534,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else { } else {
traits::ObligationCause::misc(span, self.body_id) traits::ObligationCause::misc(span, self.body_id)
}; };
obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds)); let predicates_cause = cause.clone();
obligations.extend(traits::predicates_for_generics(
move |_, _| predicates_cause.clone(),
self.param_env,
bounds,
));
// Also add an obligation for the method type being well-formed. // Also add an obligation for the method type being well-formed.
let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig)); let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig));

View file

@ -1514,8 +1514,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds); traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds);
// Convert the bounds into obligations. // Convert the bounds into obligations.
let impl_obligations = let impl_obligations = traits::predicates_for_generics(
traits::predicates_for_generics(cause, self.param_env, impl_bounds); move |_, _| cause.clone(),
self.param_env,
impl_bounds,
);
let candidate_obligations = impl_obligations let candidate_obligations = impl_obligations
.chain(norm_obligations.into_iter()) .chain(norm_obligations.into_iter())

View file

@ -36,9 +36,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
--> $DIR/associated-types-eq-3.rs:40:9 --> $DIR/associated-types-eq-3.rs:40:9
| |
LL | baz(&a); LL | baz(&a);
| --- ^^ type mismatch resolving `<isize as Foo>::A == Bar` | ^^ type mismatch resolving `<isize as Foo>::A == Bar`
| |
| required by a bound introduced by this call
| |
note: expected this to be `Bar` note: expected this to be `Bar`
--> $DIR/associated-types-eq-3.rs:12:14 --> $DIR/associated-types-eq-3.rs:12:14

View file

@ -17,10 +17,12 @@ LL | f1(2i32, 4u32);
| ~~~ | ~~~
error[E0277]: the trait bound `u32: Foo` is not satisfied error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:5 --> $DIR/associated-types-path-2.rs:29:8
| |
LL | f1(2u32, 4u32); LL | f1(2u32, 4u32);
| ^^ the trait `Foo` is not implemented for `u32` | -- ^^^^ the trait `Foo` is not implemented for `u32`
| |
| required by a bound introduced by this call
| |
= help: the trait `Foo` is implemented for `i32` = help: the trait `Foo` is implemented for `i32`
note: required by a bound in `f1` note: required by a bound in `f1`
@ -33,9 +35,7 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:14 --> $DIR/associated-types-path-2.rs:29:14
| |
LL | f1(2u32, 4u32); LL | f1(2u32, 4u32);
| -- ^^^^ the trait `Foo` is not implemented for `u32` | ^^^^ the trait `Foo` is not implemented for `u32`
| |
| required by a bound introduced by this call
| |
= help: the trait `Foo` is implemented for `i32` = help: the trait `Foo` is implemented for `i32`

View file

@ -1,10 +1,8 @@
error[E0277]: the trait bound `T: Copy` is not satisfied error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/issue-27675-unchecked-bounds.rs:15:31 --> $DIR/issue-27675-unchecked-bounds.rs:15:12
| |
LL | copy::<dyn Setup<From=T>>(t) LL | copy::<dyn Setup<From=T>>(t)
| ------------------------- ^ the trait `Copy` is not implemented for `T` | ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
| |
| required by a bound introduced by this call
| |
note: required by a bound in `copy` note: required by a bound in `copy`
--> $DIR/issue-27675-unchecked-bounds.rs:10:12 --> $DIR/issue-27675-unchecked-bounds.rs:10:12

View file

@ -1,8 +1,12 @@
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> $DIR/issue-67252-unnamed-future.rs:18:5 --> $DIR/issue-67252-unnamed-future.rs:18:11
| |
LL | spawn(async { LL | spawn(async {
| ^^^^^ future created by async block is not `Send` | ___________^
LL | | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
LL | | AFuture.await;
LL | | });
| |_____^ future created by async block is not `Send`
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*mut ()` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await

View file

@ -1,8 +1,8 @@
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> $DIR/issue-68112.rs:34:5 --> $DIR/issue-68112.rs:34:18
| |
LL | require_send(send_fut); LL | require_send(send_fut);
| ^^^^^^^^^^^^ future created by async block is not `Send` | ^^^^^^^^ future created by async block is not `Send`
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
note: future is not `Send` as it awaits another future which is not `Send` note: future is not `Send` as it awaits another future which is not `Send`
@ -17,10 +17,10 @@ LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send` | ^^^^ required by this bound in `require_send`
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> $DIR/issue-68112.rs:43:5 --> $DIR/issue-68112.rs:43:18
| |
LL | require_send(send_fut); LL | require_send(send_fut);
| ^^^^^^^^^^^^ future created by async block is not `Send` | ^^^^^^^^ future created by async block is not `Send`
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
note: future is not `Send` as it awaits another future which is not `Send` note: future is not `Send` as it awaits another future which is not `Send`
@ -35,10 +35,12 @@ LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send` | ^^^^ required by this bound in `require_send`
error[E0277]: `RefCell<i32>` cannot be shared between threads safely error[E0277]: `RefCell<i32>` cannot be shared between threads safely
--> $DIR/issue-68112.rs:60:5 --> $DIR/issue-68112.rs:60:18
| |
LL | require_send(send_fut); LL | require_send(send_fut);
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
= note: required for `Arc<RefCell<i32>>` to implement `Send` = note: required for `Arc<RefCell<i32>>` to implement `Send`

View file

@ -1,8 +1,12 @@
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> $DIR/issue-65436-raw-ptr-not-send.rs:12:5 --> $DIR/issue-65436-raw-ptr-not-send.rs:12:17
| |
LL | assert_send(async { LL | assert_send(async {
| ^^^^^^^^^^^ future created by async block is not `Send` | _________________^
LL | |
LL | | bar(Foo(std::ptr::null())).await;
LL | | })
| |_____^ future created by async block is not `Send`
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)` error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)`
--> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5 --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:18
| |
LL | is_mytrait::<(MyS2, MyS)>(); LL | is_mytrait::<(MyS2, MyS)>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2` | ^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
| |
= note: required because it appears within the type `(MyS2, MyS)` = note: required because it appears within the type `(MyS2, MyS)`
note: required by a bound in `is_mytrait` note: required by a bound in `is_mytrait`

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `u32: Signed` is not satisfied error[E0277]: the trait bound `u32: Signed` is not satisfied
--> $DIR/typeck-default-trait-impl-precedence.rs:19:5 --> $DIR/typeck-default-trait-impl-precedence.rs:19:20
| |
LL | is_defaulted::<&'static u32>(); LL | is_defaulted::<&'static u32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32` | ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
| |
= help: the trait `Signed` is implemented for `i32` = help: the trait `Signed` is implemented for `i32`
note: required for `&'static u32` to implement `Defaulted` note: required for `&'static u32` to implement `Defaulted`

View file

@ -15,8 +15,8 @@ fn main() {
x: 5, x: 5,
}; };
let s = S { //~ ERROR the trait bound `{float}: Foo` is not satisfied let s = S {
x: 5.0, x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied
}; };
let s = S { let s = S {

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `{float}: Foo` is not satisfied error[E0277]: the trait bound `{float}: Foo` is not satisfied
--> $DIR/type_wf.rs:18:13 --> $DIR/type_wf.rs:19:12
| |
LL | let s = S { LL | x: 5.0,
| ^ the trait `Foo` is not implemented for `{float}` | ^^^ the trait `Foo` is not implemented for `{float}`
| |
= help: the trait `Foo` is implemented for `i32` = help: the trait `Foo` is implemented for `i32`
note: required by a bound in `S` note: required by a bound in `S`

View file

@ -8,6 +8,8 @@ LL | num += 1;
... ...
LL | Box::new(closure) LL | Box::new(closure)
| ----------------- the requirement to implement `Fn` derives from here | ----------------- the requirement to implement `Fn` derives from here
|
= note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()`
error: aborting due to previous error error: aborting due to previous error

View file

@ -8,6 +8,8 @@ LL | vec
... ...
LL | Box::new(closure) LL | Box::new(closure)
| ----------------- the requirement to implement `Fn` derives from here | ----------------- the requirement to implement `Fn` derives from here
|
= note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec<u8>`
error: aborting due to previous error error: aborting due to previous error

View file

@ -7,7 +7,15 @@ LL | let [_, _s] = s;
| - closure is `FnOnce` because it moves the variable `s` out of its environment | - closure is `FnOnce` because it moves the variable `s` out of its environment
LL | }; LL | };
LL | expect_fn(c); LL | expect_fn(c);
| --------- the requirement to implement `Fn` derives from here | --------- - the requirement to implement `Fn` derives from here
| |
| required by a bound introduced by this call
|
note: required by a bound in `expect_fn`
--> $DIR/closure-origin-array-diagnostics.rs:5:17
|
LL | fn expect_fn<F: Fn()>(_f: F) {}
| ^^^^ required by this bound in `expect_fn`
error: aborting due to previous error error: aborting due to previous error

View file

@ -7,7 +7,15 @@ LL | let s = s.1;
| --- closure is `FnOnce` because it moves the variable `s.1` out of its environment | --- closure is `FnOnce` because it moves the variable `s.1` out of its environment
LL | }; LL | };
LL | expect_fn(c); LL | expect_fn(c);
| --------- the requirement to implement `Fn` derives from here | --------- - the requirement to implement `Fn` derives from here
| |
| required by a bound introduced by this call
|
note: required by a bound in `expect_fn`
--> $DIR/closure-origin-tuple-diagnostics.rs:5:17
|
LL | fn expect_fn<F: Fn()>(_f: F) {}
| ^^^^ required by this bound in `expect_fn`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,8 +1,14 @@
error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
--> $DIR/closure-move-sync.rs:6:13 --> $DIR/closure-move-sync.rs:6:27
| |
LL | let t = thread::spawn(|| { LL | let t = thread::spawn(|| {
| ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely | _____________-------------_^
| | |
| | required by a bound introduced by this call
LL | | recv.recv().unwrap();
LL | |
LL | | });
| |_____^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
| |
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>` = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
= note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send` = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send`
@ -18,10 +24,12 @@ LL | F: Send + 'static,
| ^^^^ required by this bound in `spawn` | ^^^^ required by this bound in `spawn`
error[E0277]: `Sender<()>` cannot be shared between threads safely error[E0277]: `Sender<()>` cannot be shared between threads safely
--> $DIR/closure-move-sync.rs:18:5 --> $DIR/closure-move-sync.rs:18:19
| |
LL | thread::spawn(|| tx.send(()).unwrap()); LL | thread::spawn(|| tx.send(()).unwrap());
| ^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely | ------------- ^^^^^^^^^^^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
| |
= help: the trait `Sync` is not implemented for `Sender<()>` = help: the trait `Sync` is not implemented for `Sender<()>`
= note: required for `&Sender<()>` to implement `Send` = note: required for `&Sender<()>` to implement `Send`

View file

@ -6,7 +6,15 @@ LL | let closure = |_| foo(x);
| | | |
| this closure implements `FnOnce`, not `Fn` | this closure implements `FnOnce`, not `Fn`
LL | bar(closure); LL | bar(closure);
| --- the requirement to implement `Fn` derives from here | --- ------- the requirement to implement `Fn` derives from here
| |
| required by a bound introduced by this call
|
note: required by a bound in `bar`
--> $DIR/closure-wrong-kind.rs:6:11
|
LL | fn bar<T: Fn(u32)>(_: T) {}
| ^^^^^^^ required by this bound in `bar`
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,9 +2,7 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied
--> $DIR/trait_objects_fail.rs:26:9 --> $DIR/trait_objects_fail.rs:26:9
| |
LL | foo(&10_u32); LL | foo(&10_u32);
| --- ^^^^^^^ the trait `Trait` is not implemented for `u32` | ^^^^^^^ the trait `Trait` is not implemented for `u32`
| |
| required by a bound introduced by this call
| |
= help: the trait `Trait<2>` is implemented for `u32` = help: the trait `Trait<2>` is implemented for `u32`
= note: required for the cast from `u32` to the object type `dyn Trait` = note: required for the cast from `u32` to the object type `dyn Trait`
@ -13,9 +11,7 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
--> $DIR/trait_objects_fail.rs:28:9 --> $DIR/trait_objects_fail.rs:28:9
| |
LL | bar(&true); LL | bar(&true);
| --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
| |
| required by a bound introduced by this call
| |
= help: the trait `Traitor<2, 3>` is implemented for `bool` = help: the trait `Traitor<2, 3>` is implemented for `bool`
= note: required for the cast from `bool` to the object type `dyn Traitor<_>` = note: required for the cast from `bool` to the object type `dyn Traitor<_>`

View file

@ -1,8 +1,8 @@
error: unconstrained generic constant error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-3.rs:17:5 --> $DIR/abstract-const-as-cast-3.rs:17:19
| |
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>(); LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
@ -26,10 +26,10 @@ LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
found type `{ O as u128 }` found type `{ O as u128 }`
error: unconstrained generic constant error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-3.rs:20:5 --> $DIR/abstract-const-as-cast-3.rs:20:19
| |
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>(); LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
@ -71,10 +71,10 @@ LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
found type `14` found type `14`
error: unconstrained generic constant error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-3.rs:35:5 --> $DIR/abstract-const-as-cast-3.rs:35:19
| |
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>(); LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
@ -98,10 +98,10 @@ LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
found type `{ O as u128 }` found type `{ O as u128 }`
error: unconstrained generic constant error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-3.rs:38:5 --> $DIR/abstract-const-as-cast-3.rs:38:19
| |
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>(); LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:` = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait` note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`

View file

@ -2,7 +2,7 @@ error[E0277]: can't drop `UnconstDrop` in const contexts
--> $DIR/const-block-const-bound.rs:20:11 --> $DIR/const-block-const-bound.rs:20:11
| |
LL | f(UnconstDrop); LL | f(UnconstDrop);
| - ^^^^^^^^^^^ expected an implementor of trait `~const Destruct` | - ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
@ -23,7 +23,7 @@ error[E0277]: can't drop `NonDrop` in const contexts
--> $DIR/const-block-const-bound.rs:22:11 --> $DIR/const-block-const-bound.rs:22:11
| |
LL | f(NonDrop); LL | f(NonDrop);
| - ^^^^^^^ expected an implementor of trait `~const Destruct` | - ^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |

View file

@ -2,7 +2,7 @@ error[E0277]: the trait bound `B<C>: Copy` is not satisfied
--> $DIR/deriving-copyclone.rs:31:13 --> $DIR/deriving-copyclone.rs:31:13
| |
LL | is_copy(B { a: 1, b: C }); LL | is_copy(B { a: 1, b: C });
| ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy` | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B<C>`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
@ -26,7 +26,7 @@ error[E0277]: the trait bound `B<C>: Clone` is not satisfied
--> $DIR/deriving-copyclone.rs:32:14 --> $DIR/deriving-copyclone.rs:32:14
| |
LL | is_clone(B { a: 1, b: C }); LL | is_clone(B { a: 1, b: C });
| -------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone` | -------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `B<C>`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
@ -50,7 +50,7 @@ error[E0277]: the trait bound `B<D>: Copy` is not satisfied
--> $DIR/deriving-copyclone.rs:35:13 --> $DIR/deriving-copyclone.rs:35:13
| |
LL | is_copy(B { a: 1, b: D }); LL | is_copy(B { a: 1, b: D });
| ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Copy` | ------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `B<D>`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
--> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:8 --> $DIR/issue-21659-show-relevant-trait-impls-1.rs:24:12
| |
LL | f1.foo(1usize); LL | f1.foo(1usize);
| ^^^ the trait `Foo<usize>` is not implemented for `Bar` | --- ^^^^^^ the trait `Foo<usize>` is not implemented for `Bar`
| |
| required by a bound introduced by this call
| |
= help: the following other types implement trait `Foo<A>`: = help: the following other types implement trait `Foo<A>`:
<Bar as Foo<i32>> <Bar as Foo<i32>>

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
--> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:8 --> $DIR/issue-21659-show-relevant-trait-impls-2.rs:28:12
| |
LL | f1.foo(1usize); LL | f1.foo(1usize);
| ^^^ the trait `Foo<usize>` is not implemented for `Bar` | --- ^^^^^^ the trait `Foo<usize>` is not implemented for `Bar`
| |
| required by a bound introduced by this call
| |
= help: the following other types implement trait `Foo<A>`: = help: the following other types implement trait `Foo<A>`:
<Bar as Foo<i16>> <Bar as Foo<i16>>

View file

@ -1,8 +1,8 @@
error[E0277]: `*const u8` cannot be sent between threads safely error[E0277]: `*const u8` cannot be sent between threads safely
--> $DIR/E0277-2.rs:16:5 --> $DIR/E0277-2.rs:16:15
| |
LL | is_send::<Foo>(); LL | is_send::<Foo>();
| ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely | ^^^ `*const u8` cannot be sent between threads safely
| |
= help: within `Foo`, the trait `Send` is not implemented for `*const u8` = help: within `Foo`, the trait `Send` is not implemented for `*const u8`
note: required because it appears within the type `Baz` note: required because it appears within the type `Baz`

View file

@ -16,10 +16,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++ | ++++++++
error[E0277]: the size for values of type `A` cannot be known at compilation time error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/extern-types-unsized.rs:25:5 --> $DIR/extern-types-unsized.rs:25:20
| |
LL | assert_sized::<Foo>(); LL | assert_sized::<Foo>();
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ^^^ doesn't have a size known at compile-time
| |
= help: within `Foo`, the trait `Sized` is not implemented for `A` = help: within `Foo`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Foo` note: required because it appears within the type `Foo`
@ -38,10 +38,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++ | ++++++++
error[E0277]: the size for values of type `A` cannot be known at compilation time error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/extern-types-unsized.rs:28:5 --> $DIR/extern-types-unsized.rs:28:20
| |
LL | assert_sized::<Bar<A>>(); LL | assert_sized::<Bar<A>>();
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ^^^^^^ doesn't have a size known at compile-time
| |
= help: within `Bar<A>`, the trait `Sized` is not implemented for `A` = help: within `Bar<A>`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Bar<A>` note: required because it appears within the type `Bar<A>`
@ -60,10 +60,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++ | ++++++++
error[E0277]: the size for values of type `A` cannot be known at compilation time error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/extern-types-unsized.rs:31:5 --> $DIR/extern-types-unsized.rs:31:20
| |
LL | assert_sized::<Bar<Bar<A>>>(); LL | assert_sized::<Bar<Bar<A>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ^^^^^^^^^^^ doesn't have a size known at compile-time
| |
= help: within `Bar<Bar<A>>`, the trait `Sized` is not implemented for `A` = help: within `Bar<Bar<A>>`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Bar<A>` note: required because it appears within the type `Bar<A>`

View file

@ -15,9 +15,7 @@ error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known
--> $DIR/feature-gate-unsized_fn_params.rs:24:9 --> $DIR/feature-gate-unsized_fn_params.rs:24:9
| |
LL | foo(*x); LL | foo(*x);
| --- ^^ doesn't have a size known at compile-time | ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
| |
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
= help: unsized fn params are gated as an unstable feature = help: unsized fn params are gated as an unstable feature

View file

@ -1,8 +1,10 @@
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
--> $DIR/send-sync.rs:8:5 --> $DIR/send-sync.rs:8:10
| |
LL | send(format_args!("{:?}", c)); LL | send(format_args!("{:?}", c));
| ^^^^ `core::fmt::Opaque` cannot be shared between threads safely | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
| |
| required by a bound introduced by this call
| |
= help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque` = help: within `[ArgumentV1<'_>]`, the trait `Sync` is not implemented for `core::fmt::Opaque`
= note: required because it appears within the type `&core::fmt::Opaque` = note: required because it appears within the type `&core::fmt::Opaque`
@ -17,10 +19,12 @@ LL | fn send<T: Send>(_: T) {}
| ^^^^ required by this bound in `send` | ^^^^ required by this bound in `send`
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
--> $DIR/send-sync.rs:9:5 --> $DIR/send-sync.rs:9:10
| |
LL | sync(format_args!("{:?}", c)); LL | sync(format_args!("{:?}", c));
| ^^^^ `core::fmt::Opaque` cannot be shared between threads safely | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::Opaque` cannot be shared between threads safely
| |
| required by a bound introduced by this call
| |
= help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque` = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::Opaque`
= note: required because it appears within the type `&core::fmt::Opaque` = note: required because it appears within the type `&core::fmt::Opaque`

View file

@ -1,8 +1,8 @@
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/drop-tracking-parent-expression.rs:24:13 --> $DIR/drop-tracking-parent-expression.rs:24:25
| |
LL | assert_send(g); LL | assert_send(g);
| ^^^^^^^^^^^ generator is not `Send` | ^ generator is not `Send`
... ...
LL | / type_combinations!( LL | / type_combinations!(
LL | | // OK LL | | // OK
@ -41,10 +41,10 @@ LL | fn assert_send<T: Send>(_thing: T) {}
= note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/drop-tracking-parent-expression.rs:24:13 --> $DIR/drop-tracking-parent-expression.rs:24:25
| |
LL | assert_send(g); LL | assert_send(g);
| ^^^^^^^^^^^ generator is not `Send` | ^ generator is not `Send`
... ...
LL | / type_combinations!( LL | / type_combinations!(
LL | | // OK LL | | // OK
@ -83,10 +83,10 @@ LL | fn assert_send<T: Send>(_thing: T) {}
= note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/drop-tracking-parent-expression.rs:24:13 --> $DIR/drop-tracking-parent-expression.rs:24:25
| |
LL | assert_send(g); LL | assert_send(g);
| ^^^^^^^^^^^ generator is not `Send` | ^ generator is not `Send`
... ...
LL | / type_combinations!( LL | / type_combinations!(
LL | | // OK LL | | // OK

View file

@ -1,8 +1,14 @@
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/drop-yield-twice.rs:7:5 --> $DIR/drop-yield-twice.rs:7:17
| |
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ generator is not `Send` | _________________^
LL | | let guard = Foo(42);
LL | | yield;
LL | | drop(guard);
LL | | yield;
LL | | })
| |_____^ generator is not `Send`
| |
= help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo` = help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield note: generator is not `Send` as this value is used across a yield

View file

@ -1,8 +1,15 @@
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36]` error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 15:36]`
--> $DIR/generator-yielding-or-returning-itself.rs:15:5 --> $DIR/generator-yielding-or-returning-itself.rs:15:34
| |
LL | want_cyclic_generator_return(|| { LL | want_cyclic_generator_return(|| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size | _____----------------------------_^
| | |
| | required by a bound introduced by this call
LL | |
LL | | if false { yield None.unwrap(); }
LL | | None.unwrap()
LL | | })
| |_____^ cyclic type of infinite size
| |
= note: closures cannot capture themselves or take themselves as argument; = note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix, this error may be the result of a recent compiler bug-fix,
@ -17,10 +24,17 @@ LL | where T: Generator<Yield = (), Return = T>
| ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return` | ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return`
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35]` error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 28:35]`
--> $DIR/generator-yielding-or-returning-itself.rs:28:5 --> $DIR/generator-yielding-or-returning-itself.rs:28:33
| |
LL | want_cyclic_generator_yield(|| { LL | want_cyclic_generator_yield(|| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size | _____---------------------------_^
| | |
| | required by a bound introduced by this call
LL | |
LL | | if false { yield None.unwrap(); }
LL | | None.unwrap()
LL | | })
| |_____^ cyclic type of infinite size
| |
= note: closures cannot capture themselves or take themselves as argument; = note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix, this error may be the result of a recent compiler bug-fix,

View file

@ -64,6 +64,7 @@ fn test2() {
//~^ ERROR `RefCell<i32>` cannot be shared between threads safely //~^ ERROR `RefCell<i32>` cannot be shared between threads safely
//~| NOTE `RefCell<i32>` cannot be shared between threads safely //~| NOTE `RefCell<i32>` cannot be shared between threads safely
//~| NOTE required for //~| NOTE required for
//~| NOTE required by a bound introduced by this call
//~| NOTE captures the following types //~| NOTE captures the following types
} }

View file

@ -1,8 +1,8 @@
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/issue-68112.rs:40:5 --> $DIR/issue-68112.rs:40:18
| |
LL | require_send(send_gen); LL | require_send(send_gen);
| ^^^^^^^^^^^^ generator is not `Send` | ^^^^^^^^ generator is not `Send`
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
note: generator is not `Send` as this value is used across a yield note: generator is not `Send` as this value is used across a yield
@ -23,10 +23,12 @@ LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send` | ^^^^ required by this bound in `require_send`
error[E0277]: `RefCell<i32>` cannot be shared between threads safely error[E0277]: `RefCell<i32>` cannot be shared between threads safely
--> $DIR/issue-68112.rs:63:5 --> $DIR/issue-68112.rs:63:18
| |
LL | require_send(send_gen); LL | require_send(send_gen);
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
= note: required for `Arc<RefCell<i32>>` to implement `Send` = note: required for `Arc<RefCell<i32>>` to implement `Send`

View file

@ -1,8 +1,15 @@
error[E0277]: `Cell<i32>` cannot be shared between threads safely error[E0277]: `Cell<i32>` cannot be shared between threads safely
--> $DIR/not-send-sync.rs:16:5 --> $DIR/not-send-sync.rs:16:17
| |
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely | _____-----------_^
| | |
| | required by a bound introduced by this call
LL | |
LL | | drop(&a);
LL | | yield;
LL | | });
| |_____^ `Cell<i32>` cannot be shared between threads safely
| |
= help: the trait `Sync` is not implemented for `Cell<i32>` = help: the trait `Sync` is not implemented for `Cell<i32>`
= note: required for `&Cell<i32>` to implement `Send` = note: required for `&Cell<i32>` to implement `Send`
@ -18,10 +25,15 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error: generator cannot be shared between threads safely error: generator cannot be shared between threads safely
--> $DIR/not-send-sync.rs:9:5 --> $DIR/not-send-sync.rs:9:17
| |
LL | assert_sync(|| { LL | assert_sync(|| {
| ^^^^^^^^^^^ generator is not `Sync` | _________________^
LL | |
LL | | let a = Cell::new(2);
LL | | yield;
LL | | });
| |_____^ generator is not `Sync`
| |
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell<i32>` = help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell<i32>`
note: generator is not `Sync` as this value is used across a yield note: generator is not `Sync` as this value is used across a yield

View file

@ -1,8 +1,15 @@
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/partial-drop.rs:14:5 --> $DIR/partial-drop.rs:14:17
| |
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ generator is not `Send` | _________________^
LL | |
LL | | // FIXME: it would be nice to make this work.
LL | | let guard = Bar { foo: Foo, x: 42 };
LL | | drop(guard.foo);
LL | | yield;
LL | | });
| |_____^ generator is not `Send`
| |
= help: within `[generator@$DIR/partial-drop.rs:14:17: 14:19]`, the trait `Send` is not implemented for `Foo` = help: within `[generator@$DIR/partial-drop.rs:14:17: 14:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield note: generator is not `Send` as this value is used across a yield
@ -22,10 +29,17 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/partial-drop.rs:22:5 --> $DIR/partial-drop.rs:22:17
| |
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ generator is not `Send` | _________________^
LL | |
LL | | // FIXME: it would be nice to make this work.
LL | | let guard = Bar { foo: Foo, x: 42 };
... |
LL | | yield;
LL | | });
| |_____^ generator is not `Send`
| |
= help: within `[generator@$DIR/partial-drop.rs:22:17: 22:19]`, the trait `Send` is not implemented for `Foo` = help: within `[generator@$DIR/partial-drop.rs:22:17: 22:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield note: generator is not `Send` as this value is used across a yield
@ -45,10 +59,17 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/partial-drop.rs:32:5 --> $DIR/partial-drop.rs:32:17
| |
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ generator is not `Send` | _________________^
LL | |
LL | | // FIXME: it would be nice to make this work.
LL | | let guard = Bar { foo: Foo, x: 42 };
... |
LL | | yield;
LL | | });
| |_____^ generator is not `Send`
| |
= help: within `[generator@$DIR/partial-drop.rs:32:17: 32:19]`, the trait `Send` is not implemented for `Foo` = help: within `[generator@$DIR/partial-drop.rs:32:17: 32:19]`, the trait `Send` is not implemented for `Foo`
note: generator is not `Send` as this value is used across a yield note: generator is not `Send` as this value is used across a yield

View file

@ -1,8 +1,8 @@
error: generator cannot be sent between threads safely error: generator cannot be sent between threads safely
--> $DIR/generator-print-verbose-1.rs:37:5 --> $DIR/generator-print-verbose-1.rs:37:18
| |
LL | require_send(send_gen); LL | require_send(send_gen);
| ^^^^^^^^^^^^ generator is not `Send` | ^^^^^^^^ generator is not `Send`
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
note: generator is not `Send` as this value is used across a yield note: generator is not `Send` as this value is used across a yield
@ -21,10 +21,12 @@ LL | fn require_send(_: impl Send) {}
| ^^^^ required by this bound in `require_send` | ^^^^ required by this bound in `require_send`
error[E0277]: `RefCell<i32>` cannot be shared between threads safely error[E0277]: `RefCell<i32>` cannot be shared between threads safely
--> $DIR/generator-print-verbose-1.rs:56:5 --> $DIR/generator-print-verbose-1.rs:56:18
| |
LL | require_send(send_gen); LL | require_send(send_gen);
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely | ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
| |
= help: the trait `Sync` is not implemented for `RefCell<i32>` = help: the trait `Sync` is not implemented for `RefCell<i32>`
= note: required for `Arc<RefCell<i32>>` to implement `Send` = note: required for `Arc<RefCell<i32>>` to implement `Send`

View file

@ -1,8 +1,15 @@
error[E0277]: `Cell<i32>` cannot be shared between threads safely error[E0277]: `Cell<i32>` cannot be shared between threads safely
--> $DIR/generator-print-verbose-2.rs:19:5 --> $DIR/generator-print-verbose-2.rs:19:17
| |
LL | assert_send(|| { LL | assert_send(|| {
| ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely | _____-----------_^
| | |
| | required by a bound introduced by this call
LL | |
LL | | drop(&a);
LL | | yield;
LL | | });
| |_____^ `Cell<i32>` cannot be shared between threads safely
| |
= help: the trait `Sync` is not implemented for `Cell<i32>` = help: the trait `Sync` is not implemented for `Cell<i32>`
= note: required for `&'_#4r Cell<i32>` to implement `Send` = note: required for `&'_#4r Cell<i32>` to implement `Send`
@ -18,10 +25,15 @@ LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error: generator cannot be shared between threads safely error: generator cannot be shared between threads safely
--> $DIR/generator-print-verbose-2.rs:12:5 --> $DIR/generator-print-verbose-2.rs:12:17
| |
LL | assert_sync(|| { LL | assert_sync(|| {
| ^^^^^^^^^^^ generator is not `Sync` | _________________^
LL | |
LL | | let a = Cell::new(2);
LL | | yield;
LL | | });
| |_____^ generator is not `Sync`
| |
= help: within `[main::{closure#0} upvar_tys=() {Cell<i32>, ()}]`, the trait `Sync` is not implemented for `Cell<i32>` = help: within `[main::{closure#0} upvar_tys=() {Cell<i32>, ()}]`, the trait `Sync` is not implemented for `Cell<i32>`
note: generator is not `Sync` as this value is used across a yield note: generator is not `Sync` as this value is used across a yield

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
--> $DIR/issue-88460.rs:30:5 --> $DIR/issue-88460.rs:30:10
| |
LL | test(Foo); LL | test(Foo);
| ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` | ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
| |
| required by a bound introduced by this call
| |
= help: the trait `Marker` is implemented for `()` = help: the trait `Marker` is implemented for `()`
note: required by a bound in `test` note: required by a bound in `test`

View file

@ -1,8 +1,10 @@
error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
--> $DIR/issue-62529-3.rs:25:9 --> $DIR/issue-62529-3.rs:25:14
| |
LL | call(f, ()); LL | call(f, ());
| ^^^^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` | ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
| |
| required by a bound introduced by this call
| |
= note: expected a closure with arguments `((),)` = note: expected a closure with arguments `((),)`
found a closure with arguments `(<_ as ATC<'a>>::Type,)` found a closure with arguments `(<_ as ATC<'a>>::Type,)`

View file

@ -2,7 +2,9 @@ error[E0283]: type annotations needed
--> $DIR/issue-71732.rs:18:10 --> $DIR/issue-71732.rs:18:10
| |
LL | .get(&"key".into()) LL | .get(&"key".into())
| ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get` | ^^^ ------------- type must be known at this point
| |
| cannot infer type of the type parameter `Q` declared on the associated function `get`
| |
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
- impl Borrow<str> for String; - impl Borrow<str> for String;
@ -13,7 +15,7 @@ note: required by a bound in `HashMap::<K, V, S>::get`
| |
LL | K: Borrow<Q>, LL | K: Borrow<Q>,
| ^^^^^^^^^ required by this bound in `HashMap::<K, V, S>::get` | ^^^^^^^^^ required by this bound in `HashMap::<K, V, S>::get`
help: consider specifying the type argument in the function call help: consider specifying the generic argument
| |
LL | .get::<Q>(&"key".into()) LL | .get::<Q>(&"key".into())
| +++++ | +++++

View file

@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`! LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
| --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` | --- ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
| | | |
| type must be known at this point | required by a bound introduced by this call
| |
= note: cannot satisfy `_: Clone` = note: cannot satisfy `_: Clone`
note: required by a bound in `foo` note: required by a bound in `foo`

View file

@ -4,7 +4,7 @@ error[E0283]: type annotations needed
LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`! LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
| -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen` | -------- ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
| | | |
| type must be known at this point | required by a bound introduced by this call
| |
= note: cannot satisfy `_: Clone` = note: cannot satisfy `_: Clone`
note: required by a bound in `Foo::bar` note: required by a bound in `Foo::bar`

View file

@ -1,8 +1,10 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> $DIR/interior-mutability.rs:5:5 --> $DIR/interior-mutability.rs:5:18
| |
LL | catch_unwind(|| { x.set(23); }); LL | catch_unwind(|| { x.set(23); });
| ^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
| required by a bound introduced by this call
| |
= help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` = help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `Cell<i32>` = note: required because it appears within the type `Cell<i32>`

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `X: Ord` is not satisfied error[E0277]: the trait bound `X: Ord` is not satisfied
--> $DIR/issue-20162.rs:5:7 --> $DIR/issue-20162.rs:5:5
| |
LL | b.sort(); LL | b.sort();
| ^^^^ the trait `Ord` is not implemented for `X` | ^ ---- required by a bound introduced by this call
| |
| the trait `Ord` is not implemented for `X`
| |
note: required by a bound in `slice::<impl [T]>::sort` note: required by a bound in `slice::<impl [T]>::sort`
--> $SRC_DIR/alloc/src/slice.rs:LL:COL --> $SRC_DIR/alloc/src/slice.rs:LL:COL

View file

@ -2,7 +2,7 @@ error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cann
--> $DIR/issue-20605.rs:2:17 --> $DIR/issue-20605.rs:2:17
| |
LL | for item in *things { *item = 0 } LL | for item in *things { *item = 0 }
| ^^^^^^^ expected an implementor of trait `IntoIterator` | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
| |
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator` = note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`

View file

@ -1,8 +1,8 @@
error[E0277]: `Rc<()>` cannot be sent between threads safely error[E0277]: `Rc<()>` cannot be sent between threads safely
--> $DIR/issue-21763.rs:9:5 --> $DIR/issue-21763.rs:9:11
| |
LL | foo::<HashMap<Rc<()>, Rc<()>>>(); LL | foo::<HashMap<Rc<()>, Rc<()>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
| |
= help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>`
= note: required because it appears within the type `(Rc<()>, Rc<()>)` = note: required because it appears within the type `(Rc<()>, Rc<()>)`

View file

@ -4,12 +4,12 @@ pub fn get_tok(it: &mut IntoIter<u8>) {
let mut found_e = false; let mut found_e = false;
let temp: Vec<u8> = it let temp: Vec<u8> = it
//~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
.take_while(|&x| { .take_while(|&x| {
found_e = true; found_e = true;
false false
}) })
.cloned() .cloned()
//~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
.collect(); //~ ERROR the method .collect(); //~ ERROR the method
} }

View file

@ -1,8 +1,16 @@
error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>` to be an iterator that yields `&_`, but it yields `u8` error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>` to be an iterator that yields `&_`, but it yields `u8`
--> $DIR/issue-31173.rs:11:10 --> $DIR/issue-31173.rs:6:25
| |
LL | .cloned() LL | let temp: Vec<u8> = it
| ^^^^^^ expected reference, found `u8` | _________________________^
LL | |
LL | | .take_while(|&x| {
LL | | found_e = true;
LL | | false
LL | | })
| |__________^ expected reference, found `u8`
LL | .cloned()
| ------ required by a bound introduced by this call
| |
= note: expected reference `&_` = note: expected reference `&_`
found type `u8` found type `u8`
@ -12,11 +20,11 @@ note: required by a bound in `cloned`
LL | Self: Sized + Iterator<Item = &'a T>, LL | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in `cloned` | ^^^^^^^^^^^^ required by this bound in `cloned`
error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>`, but its trait bounds were not satisfied error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>`, but its trait bounds were not satisfied
--> $DIR/issue-31173.rs:13:10 --> $DIR/issue-31173.rs:13:10
| |
LL | .collect(); LL | .collect();
| ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds | ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>` due to unsatisfied trait bounds
| |
::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL ::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
| |
@ -29,10 +37,10 @@ LL | pub struct Cloned<I> {
| -------------------- doesn't satisfy `_: Iterator` | -------------------- doesn't satisfy `_: Iterator`
| |
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_` `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]> as Iterator>::Item = &_`
which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
`Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -1,8 +1,10 @@
error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)` error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
--> $DIR/issue-33941.rs:6:36 --> $DIR/issue-33941.rs:6:14
| |
LL | for _ in HashMap::new().iter().cloned() {} LL | for _ in HashMap::new().iter().cloned() {}
| ^^^^^^ expected reference, found tuple | ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call
| |
| expected reference, found tuple
| |
= note: expected reference `&_` = note: expected reference `&_`
found tuple `(&_, &_)` found tuple `(&_, &_)`

View file

@ -13,10 +13,12 @@ LL | let sr: Vec<(u32, _, _)> = vec![];
| + | +
error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()` error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
--> $DIR/issue-34334.rs:5:87 --> $DIR/issue-34334.rs:5:33
| |
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
| ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
| |
| value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
| |
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>` = help: the trait `FromIterator<T>` is implemented for `Vec<T>`

View file

@ -7,7 +7,15 @@ LL | farewell.push_str("!!!");
| -------- closure is `FnMut` because it mutates the variable `farewell` here | -------- closure is `FnMut` because it mutates the variable `farewell` here
... ...
LL | apply(diary); LL | apply(diary);
| ----- the requirement to implement `Fn` derives from here | ----- ----- the requirement to implement `Fn` derives from here
| |
| required by a bound introduced by this call
|
note: required by a bound in `apply`
--> $DIR/issue-34349.rs:11:32
|
LL | fn apply<F>(f: F) where F: Fn() {
| ^^^^ required by this bound in `apply`
error: aborting due to previous error error: aborting due to previous error

View file

@ -30,4 +30,5 @@ fn main() {
assert_eq!(Foo::Bar, i); assert_eq!(Foo::Bar, i);
//~^ ERROR binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}` [E0369] //~^ ERROR binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}` [E0369]
//~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277] //~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277]
//~| ERROR `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` [E0277]
} }

View file

@ -106,7 +106,26 @@ LL | assert_eq!(Foo::Bar, i);
and 68 others and 68 others
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 9 previous errors error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
--> $DIR/issue-59488.rs:30:5
|
LL | assert_eq!(Foo::Bar, i);
| ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}`
= help: the following other types implement trait `Debug`:
extern "C" fn() -> Ret
extern "C" fn(A, B) -> Ret
extern "C" fn(A, B, ...) -> Ret
extern "C" fn(A, B, C) -> Ret
extern "C" fn(A, B, C, ...) -> Ret
extern "C" fn(A, B, C, D) -> Ret
extern "C" fn(A, B, C, D, ...) -> Ret
extern "C" fn(A, B, C, D, E) -> Ret
and 68 others
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0277, E0308, E0369. Some errors have detailed explanations: E0277, E0308, E0369.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `&u32: Foo` is not satisfied error[E0277]: the trait bound `&u32: Foo` is not satisfied
--> $DIR/issue-60218.rs:18:27 --> $DIR/issue-60218.rs:18:19
| |
LL | trigger_error(vec![], |x: &u32| x) LL | trigger_error(vec![], |x: &u32| x)
| ------------- ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32` | ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |

View file

@ -1,8 +1,10 @@
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64` error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:39 --> $DIR/issue-66923-show-error-for-correct-call.rs:8:24
| |
LL | let x2: Vec<f64> = x1.into_iter().collect(); LL | let x2: Vec<f64> = x1.into_iter().collect();
| ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>` | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
| |
| value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
| |
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>` = help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>` = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
@ -13,10 +15,12 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64` error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:29 --> $DIR/issue-66923-show-error-for-correct-call.rs:12:14
| |
LL | let x3 = x1.into_iter().collect::<Vec<f64>>(); LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
| ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>` | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
| |
| value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
| |
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>` = help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>` = help: the trait `FromIterator<T>` is implemented for `Vec<T>`

View file

@ -16,7 +16,7 @@ error[E0283]: type annotations needed
LL | println!("{}", 23u64.test(xs.iter().sum())); LL | println!("{}", 23u64.test(xs.iter().sum()));
| ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
| | | |
| type must be known at this point | required by a bound introduced by this call
| |
note: multiple `impl`s satisfying `u64: Test<_>` found note: multiple `impl`s satisfying `u64: Test<_>` found
--> $DIR/issue-69455.rs:11:1 --> $DIR/issue-69455.rs:11:1

View file

@ -4,4 +4,5 @@ fn main() {
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()` //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
//~| NOTE required by a bound in `collect` //~| NOTE required by a bound in `collect`
//~| NOTE required by a bound introduced by this call
} }

View file

@ -1,8 +1,10 @@
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
--> $DIR/collect-into-array.rs:3:39 --> $DIR/collect-into-array.rs:3:31
| |
LL | let whatever: [u32; 10] = (0..10).collect(); LL | let whatever: [u32; 10] = (0..10).collect();
| ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()` | ^^^^^^^ ------- required by a bound introduced by this call
| |
| try collecting into a `Vec<{integer}>`, then using `.try_into()`
| |
= help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]` = help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]`
note: required by a bound in `collect` note: required by a bound in `collect`

View file

@ -1,15 +1,20 @@
fn process_slice(data: &[i32]) { fn process_slice(data: &[i32]) {
//~^ NOTE required by a bound in this //~^ NOTE required by a bound in this
//~| NOTE required by a bound in this
todo!() todo!()
} }
fn main() { fn main() {
let some_generated_vec = (0..10).collect(); let some_generated_vec = (0..10).collect();
//~^ ERROR the size for values of type `[i32]` cannot be known at compilation time //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time
//~| ERROR the size for values of type `[i32]` cannot be known at compilation time
//~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size
//~| NOTE try explicitly collecting into a `Vec<{integer}>` //~| NOTE try explicitly collecting into a `Vec<{integer}>`
//~| NOTE required by a bound in `collect` //~| NOTE required by a bound in `collect`
//~| NOTE required by a bound in `collect`
//~| NOTE all local variables must have a statically known size //~| NOTE all local variables must have a statically known size
//~| NOTE doesn't have a size known at compile-time //~| NOTE doesn't have a size known at compile-time
//~| NOTE doesn't have a size known at compile-time
//~| NOTE required by a bound introduced by this call
process_slice(&some_generated_vec); process_slice(&some_generated_vec);
} }

View file

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> $DIR/collect-into-slice.rs:7:9 --> $DIR/collect-into-slice.rs:8:9
| |
LL | let some_generated_vec = (0..10).collect(); LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -8,11 +8,26 @@ LL | let some_generated_vec = (0..10).collect();
= note: all local variables must have a statically known size = note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature = help: unsized locals are gated as an unstable feature
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> $DIR/collect-into-slice.rs:7:38 --> $DIR/collect-into-slice.rs:8:38
| |
LL | let some_generated_vec = (0..10).collect(); LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^ try explicitly collecting into a `Vec<{integer}>` | ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[i32]`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^ required by this bound in `collect`
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
--> $DIR/collect-into-slice.rs:8:30
|
LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^ ------- required by a bound introduced by this call
| |
| try explicitly collecting into a `Vec<{integer}>`
| |
= help: the trait `FromIterator<{integer}>` is not implemented for `[i32]` = help: the trait `FromIterator<{integer}>` is not implemented for `[i32]`
note: required by a bound in `collect` note: required by a bound in `collect`
@ -21,6 +36,6 @@ note: required by a bound in `collect`
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
error: aborting due to 2 previous errors error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View file

@ -11,5 +11,5 @@ fn take_param<T:Foo>(foo: &T) { }
fn main() { fn main() {
let x: Box<_> = Box::new(3); let x: Box<_> = Box::new(3);
take_param(&x); take_param(&x);
//~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied //~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied
} }

View file

@ -1,4 +1,4 @@
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
--> $DIR/kindck-impl-type-params-2.rs:13:16 --> $DIR/kindck-impl-type-params-2.rs:13:16
| |
LL | take_param(&x); LL | take_param(&x);

View file

@ -1,4 +1,4 @@
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
--> $DIR/kindck-inherited-copy-bound.rs:21:16 --> $DIR/kindck-inherited-copy-bound.rs:21:16
| |
LL | take_param(&x); LL | take_param(&x);

View file

@ -1,4 +1,4 @@
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
--> $DIR/kindck-inherited-copy-bound.rs:21:16 --> $DIR/kindck-inherited-copy-bound.rs:21:16
| |
LL | take_param(&x); LL | take_param(&x);

View file

@ -1,10 +1,12 @@
error[E0277]: `Rc<usize>` cannot be sent between threads safely error[E0277]: `Rc<usize>` cannot be sent between threads safely
--> $DIR/kindck-nonsendable-1.rs:9:5 --> $DIR/kindck-nonsendable-1.rs:9:9
| |
LL | bar(move|| foo(x)); LL | bar(move|| foo(x));
| ^^^ ------ within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]` | --- ------^^^^^^^
| | | | |
| `Rc<usize>` cannot be sent between threads safely | | `Rc<usize>` cannot be sent between threads safely
| | within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`
| required by a bound introduced by this call
| |
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc<usize>` = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc<usize>`
note: required because it's used within this closure note: required because it's used within this closure

View file

@ -1,8 +1,8 @@
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
--> $DIR/kindck-send-object.rs:12:5 --> $DIR/kindck-send-object.rs:12:19
| |
LL | assert_send::<&'static (dyn Dummy + 'static)>(); LL | assert_send::<&'static (dyn Dummy + 'static)>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
| |
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
@ -13,10 +13,10 @@ LL | fn assert_send<T:Send>() { }
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error[E0277]: `dyn Dummy` cannot be sent between threads safely error[E0277]: `dyn Dummy` cannot be sent between threads safely
--> $DIR/kindck-send-object.rs:17:5 --> $DIR/kindck-send-object.rs:17:19
| |
LL | assert_send::<Box<dyn Dummy>>(); LL | assert_send::<Box<dyn Dummy>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
| |
= help: the trait `Send` is not implemented for `dyn Dummy` = help: the trait `Send` is not implemented for `dyn Dummy`
= note: required for `Unique<dyn Dummy>` to implement `Send` = note: required for `Unique<dyn Dummy>` to implement `Send`

View file

@ -1,8 +1,8 @@
error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
--> $DIR/kindck-send-object1.rs:10:5 --> $DIR/kindck-send-object1.rs:10:19
| |
LL | assert_send::<&'a dyn Dummy>(); LL | assert_send::<&'a dyn Dummy>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely | ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
| |
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`
= note: required for `&'a (dyn Dummy + 'a)` to implement `Send` = note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
@ -13,10 +13,10 @@ LL | fn assert_send<T:Send+'static>() { }
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
--> $DIR/kindck-send-object1.rs:28:5 --> $DIR/kindck-send-object1.rs:28:19
| |
LL | assert_send::<Box<dyn Dummy + 'a>>(); LL | assert_send::<Box<dyn Dummy + 'a>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
| |
= help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)`
= note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send`

View file

@ -1,8 +1,8 @@
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
--> $DIR/kindck-send-object2.rs:7:5 --> $DIR/kindck-send-object2.rs:7:19
| |
LL | assert_send::<&'static dyn Dummy>(); LL | assert_send::<&'static dyn Dummy>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
| |
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
@ -13,10 +13,10 @@ LL | fn assert_send<T:Send>() { }
| ^^^^ required by this bound in `assert_send` | ^^^^ required by this bound in `assert_send`
error[E0277]: `dyn Dummy` cannot be sent between threads safely error[E0277]: `dyn Dummy` cannot be sent between threads safely
--> $DIR/kindck-send-object2.rs:12:5 --> $DIR/kindck-send-object2.rs:12:19
| |
LL | assert_send::<Box<dyn Dummy>>(); LL | assert_send::<Box<dyn Dummy>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
| |
= help: the trait `Send` is not implemented for `dyn Dummy` = help: the trait `Send` is not implemented for `dyn Dummy`
= note: required for `Unique<dyn Dummy>` to implement `Send` = note: required for `Unique<dyn Dummy>` to implement `Send`

View file

@ -1,8 +1,8 @@
error[E0277]: `*mut u8` cannot be sent between threads safely error[E0277]: `*mut u8` cannot be sent between threads safely
--> $DIR/kindck-send-owned.rs:12:5 --> $DIR/kindck-send-owned.rs:12:19
| |
LL | assert_send::<Box<*mut u8>>(); LL | assert_send::<Box<*mut u8>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
| |
= help: the trait `Send` is not implemented for `*mut u8` = help: the trait `Send` is not implemented for `*mut u8`
= note: required for `Unique<*mut u8>` to implement `Send` = note: required for `Unique<*mut u8>` to implement `Send`

View file

@ -1,8 +1,10 @@
error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_` error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_`
--> $DIR/branches.rs:19:28 --> $DIR/branches.rs:19:9
| |
LL | std::iter::empty().collect() LL | std::iter::empty().collect()
| ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>` | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
| |
| value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
| |
= help: the trait `FromIterator<_>` is not implemented for `Bar` = help: the trait `FromIterator<_>` is not implemented for `Bar`
note: required by a bound in `collect` note: required by a bound in `collect`

View file

@ -1,8 +1,10 @@
error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_` error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_`
--> $DIR/recursion4.rs:10:28 --> $DIR/recursion4.rs:10:9
| |
LL | x = std::iter::empty().collect(); LL | x = std::iter::empty().collect();
| ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>` | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
| |
| value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
| |
= help: the trait `FromIterator<_>` is not implemented for `Foo` = help: the trait `FromIterator<_>` is not implemented for `Foo`
note: required by a bound in `collect` note: required by a bound in `collect`
@ -12,10 +14,12 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_` error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_`
--> $DIR/recursion4.rs:19:28 --> $DIR/recursion4.rs:19:9
| |
LL | x = std::iter::empty().collect(); LL | x = std::iter::empty().collect();
| ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>` | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
| |
| value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
| |
= help: the trait `FromIterator<_>` is not implemented for `impl Debug` = help: the trait `FromIterator<_>` is not implemented for `impl Debug`
note: required by a bound in `collect` note: required by a bound in `collect`

View file

@ -1,8 +1,10 @@
error[E0277]: `Foo` doesn't implement `Debug` error[E0277]: `Foo` doesn't implement `Debug`
--> $DIR/method-help-unsatisfied-bound.rs:5:7 --> $DIR/method-help-unsatisfied-bound.rs:5:5
| |
LL | a.unwrap(); LL | a.unwrap();
| ^^^^^^ `Foo` cannot be formatted using `{:?}` | ^ ------ required by a bound introduced by this call
| |
| `Foo` cannot be formatted using `{:?}`
| |
= help: the trait `Debug` is not implemented for `Foo` = help: the trait `Debug` is not implemented for `Foo`
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
--> $DIR/defaulted-never-note.rs:30:5 --> $DIR/defaulted-never-note.rs:30:9
| |
LL | foo(_x); LL | foo(_x);
| ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` | --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
| |
| required by a bound introduced by this call
| |
= help: the trait `ImplementedForUnitButNotNever` is implemented for `()` = help: the trait `ImplementedForUnitButNotNever` is implemented for `()`
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information) = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)

View file

@ -32,6 +32,7 @@ fn smeg() {
//[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented //[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
//[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()` //[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()`
//[fallback]~| NOTE this error might have been caused //[fallback]~| NOTE this error might have been caused
//[fallback]~| NOTE required by a bound introduced by this call
//[fallback]~| HELP did you intend //[fallback]~| HELP did you intend
} }

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `!: Test` is not satisfied error[E0277]: the trait bound `!: Test` is not satisfied
--> $DIR/diverging-fallback-no-leak.rs:17:5 --> $DIR/diverging-fallback-no-leak.rs:17:23
| |
LL | unconstrained_arg(return); LL | unconstrained_arg(return);
| ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!` | ----------------- ^^^^^^ the trait `Test` is not implemented for `!`
| |
| required by a bound introduced by this call
| |
= help: the following other types implement trait `Test`: = help: the following other types implement trait `Test`:
() ()

View file

@ -1,8 +1,12 @@
error[E0277]: the trait bound `(): T` is not satisfied error[E0277]: the trait bound `(): T` is not satisfied
--> $DIR/feature-gate-never_type_fallback.rs:10:5 --> $DIR/feature-gate-never_type_fallback.rs:10:9
| |
LL | foo(panic!()) LL | foo(panic!())
| ^^^ the trait `T` is not implemented for `()` | --- ^^^^^^^^
| | |
| | the trait `T` is not implemented for `()`
| | this tail expression is of type `_`
| required by a bound introduced by this call
| |
note: required by a bound in `foo` note: required by a bound in `foo`
--> $DIR/feature-gate-never_type_fallback.rs:13:16 --> $DIR/feature-gate-never_type_fallback.rs:13:16

View file

@ -1,8 +1,10 @@
error[E0277]: the trait bound `E: From<()>` is not satisfied error[E0277]: the trait bound `E: From<()>` is not satisfied
--> $DIR/never-value-fallback-issue-66757.rs:28:5 --> $DIR/never-value-fallback-issue-66757.rs:28:26
| |
LL | <E as From<_>>::from(never); LL | <E as From<_>>::from(never);
| ^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `E` | -------------------- ^^^^^ the trait `From<()>` is not implemented for `E`
| |
| required by a bound introduced by this call
| |
= help: the trait `From<!>` is implemented for `E` = help: the trait `From<!>` is implemented for `E`

View file

@ -1,10 +1,17 @@
error[E0277]: `Rc<()>` cannot be sent between threads safely error[E0277]: `Rc<()>` cannot be sent between threads safely
--> $DIR/no-send-res-ports.rs:25:5 --> $DIR/no-send-res-ports.rs:25:19
| |
LL | thread::spawn(move|| { LL | thread::spawn(move|| {
| ^^^^^^^^^^^^^ ------ within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]` | ------------- ^-----
| | | | |
| `Rc<()>` cannot be sent between threads safely | _____|_____________within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`
| | |
| | required by a bound introduced by this call
LL | |
LL | | let y = x;
LL | | println!("{:?}", y);
LL | | });
| |_____^ `Rc<()>` cannot be sent between threads safely
| |
= help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>` = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>`
note: required because it appears within the type `Port<()>` note: required because it appears within the type `Port<()>`

View file

@ -1,11 +1,13 @@
error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]` error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
--> $DIR/not-clone-closure.rs:11:23 --> $DIR/not-clone-closure.rs:11:17
| |
LL | let hello = move || { LL | let hello = move || {
| ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]` | ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
... ...
LL | let hello = hello.clone(); LL | let hello = hello.clone();
| ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S` | ^^^^^ ----- required by a bound introduced by this call
| |
| within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
| |
note: required because it's used within this closure note: required because it's used within this closure
--> $DIR/not-clone-closure.rs:7:17 --> $DIR/not-clone-closure.rs:7:17

View file

@ -1,8 +1,8 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> $DIR/not-panic-safe-2.rs:10:5 --> $DIR/not-panic-safe-2.rs:10:14
| |
LL | assert::<Rc<RefCell<i32>>>(); LL | assert::<Rc<RefCell<i32>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | ^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `RefCell<i32>` = note: required because it appears within the type `RefCell<i32>`
@ -14,10 +14,10 @@ LL | fn assert<T: UnwindSafe + ?Sized>() {}
| ^^^^^^^^^^ required by this bound in `assert` | ^^^^^^^^^^ required by this bound in `assert`
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> $DIR/not-panic-safe-2.rs:10:5 --> $DIR/not-panic-safe-2.rs:10:14
| |
LL | assert::<Rc<RefCell<i32>>>(); LL | assert::<Rc<RefCell<i32>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | ^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>` = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
= note: required because it appears within the type `Cell<isize>` = note: required because it appears within the type `Cell<isize>`

View file

@ -1,8 +1,8 @@
error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary error[E0277]: the type `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> $DIR/not-panic-safe-3.rs:10:5 --> $DIR/not-panic-safe-3.rs:10:14
| |
LL | assert::<Arc<RefCell<i32>>>(); LL | assert::<Arc<RefCell<i32>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | ^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>` = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
= note: required because it appears within the type `RefCell<i32>` = note: required because it appears within the type `RefCell<i32>`
@ -14,10 +14,10 @@ LL | fn assert<T: UnwindSafe + ?Sized>() {}
| ^^^^^^^^^^ required by this bound in `assert` | ^^^^^^^^^^ required by this bound in `assert`
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> $DIR/not-panic-safe-3.rs:10:5 --> $DIR/not-panic-safe-3.rs:10:14
| |
LL | assert::<Arc<RefCell<i32>>>(); LL | assert::<Arc<RefCell<i32>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | ^^^^^^^^^^^^^^^^^ `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
= help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>` = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
= note: required because it appears within the type `Cell<isize>` = note: required because it appears within the type `Cell<isize>`

Some files were not shown because too many files have changed in this diff Show more