mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 06:26:55 +00:00
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:
commit
0b71ffca18
@ -740,12 +740,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
err.help("...or use `match` instead of `let...else`");
|
||||
}
|
||||
_ => {
|
||||
if let ObligationCauseCode::BindingObligation(_, binding_span) =
|
||||
cause.code().peel_derives()
|
||||
if let ObligationCauseCode::BindingObligation(_, span)
|
||||
| ObligationCauseCode::ExprBindingObligation(_, span, ..)
|
||||
= cause.code().peel_derives()
|
||||
&& let TypeError::RegionsPlaceholderMismatch = terr
|
||||
{
|
||||
if matches!(terr, TypeError::RegionsPlaceholderMismatch) {
|
||||
err.span_note(*binding_span, "the lifetime requirement is introduced here");
|
||||
}
|
||||
err.span_note(*span, "the lifetime requirement is introduced here");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else {
|
||||
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;
|
||||
};
|
||||
let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type");
|
||||
|
@ -211,7 +211,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
||||
);
|
||||
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(
|
||||
self.tcx().def_span(def_id),
|
||||
|
@ -232,7 +232,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
ObligationCauseCode::MatchImpl(parent, ..) => parent.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`
|
||||
// lifetime as above, but called using a fully-qualified path to the method:
|
||||
|
@ -390,10 +390,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
if matches!(
|
||||
&trace.cause.code().peel_derives(),
|
||||
ObligationCauseCode::BindingObligation(..)
|
||||
| ObligationCauseCode::ExprBindingObligation(..)
|
||||
) =>
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
let span = *span;
|
||||
|
@ -97,7 +97,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
||||
cause.span,
|
||||
sup_type,
|
||||
match cause.code().peel_derives() {
|
||||
ObligationCauseCode::BindingObligation(_, span) => Some(*span),
|
||||
ObligationCauseCode::BindingObligation(_, span)
|
||||
| ObligationCauseCode::ExprBindingObligation(_, span, ..) => Some(*span),
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
|
@ -234,13 +234,23 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
/// This is the trait reference from the given projection.
|
||||
ProjectionWf(ty::ProjectionTy<'tcx>),
|
||||
|
||||
/// In an impl of trait `X` for type `Y`, type `Y` must
|
||||
/// also implement all supertraits of `X`.
|
||||
/// Must satisfy all of the where-clause predicates of the
|
||||
/// given item.
|
||||
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),
|
||||
|
||||
/// 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`.
|
||||
ReferenceOutlivesReferent(Ty<'tcx>),
|
||||
|
||||
|
@ -122,6 +122,21 @@ pub struct 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]
|
||||
pub fn count(&self) -> usize {
|
||||
self.parent_count + self.params.len()
|
||||
|
@ -664,6 +664,16 @@ impl Span {
|
||||
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.
|
||||
pub fn edition(self) -> edition::Edition {
|
||||
self.ctxt().edition()
|
||||
|
@ -860,8 +860,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
return;
|
||||
err
|
||||
}
|
||||
|
||||
ty::PredicateKind::WellFormed(ty) => {
|
||||
@ -1564,6 +1563,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||
obligation.cause.code().peel_derives(),
|
||||
ObligationCauseCode::ItemObligation(_)
|
||||
| ObligationCauseCode::BindingObligation(_, _)
|
||||
| ObligationCauseCode::ExprItemObligation(..)
|
||||
| ObligationCauseCode::ExprBindingObligation(..)
|
||||
| ObligationCauseCode::ObjectCastObligation(..)
|
||||
| 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());
|
||||
} else if let (
|
||||
Ok(ref snippet),
|
||||
&ObligationCauseCode::BindingObligation(def_id, _),
|
||||
) =
|
||||
(self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code())
|
||||
} else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..)
|
||||
= *obligation.cause.code()
|
||||
{
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
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,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
let (
|
||||
ty::PredicateKind::Trait(pred),
|
||||
&ObligationCauseCode::BindingObligation(item_def_id, span),
|
||||
) = (
|
||||
obligation.predicate.kind().skip_binder(),
|
||||
obligation.cause.code().peel_derives(),
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
|
||||
let (ObligationCauseCode::BindingObligation(item_def_id, span)
|
||||
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
|
||||
= *obligation.cause.code().peel_derives() else { return; };
|
||||
debug!(?pred, ?item_def_id, ?span);
|
||||
|
||||
let (Some(node), true) = (
|
||||
|
@ -143,7 +143,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
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
|
||||
// from other traits? That would require name resolution,
|
||||
|
@ -671,11 +671,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> bool {
|
||||
// It only make sense when suggesting dereferences for arguments
|
||||
let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else {
|
||||
return false;
|
||||
};
|
||||
let param_env = obligation.param_env;
|
||||
let body_id = obligation.cause.body_id;
|
||||
let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code()
|
||||
else { return false; };
|
||||
let Some(typeck_results) = self.in_progress_typeck_results
|
||||
else { return false; };
|
||||
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 mut real_trait_pred = trait_pred;
|
||||
let mut code = obligation.cause.code();
|
||||
@ -687,9 +692,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
|
||||
// Skipping binder here, remapping below
|
||||
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() {
|
||||
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)| {
|
||||
// Re-add the `&`
|
||||
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
|
||||
let real_trait_pred_and_ty =
|
||||
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
|
||||
let obligation = self
|
||||
.mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred_and_ty);
|
||||
let obligation = self.mk_trait_obligation_with_new_self_ty(
|
||||
obligation.param_env,
|
||||
real_trait_pred_and_ty,
|
||||
);
|
||||
Some(steps).filter(|_| self.predicate_may_hold(&obligation))
|
||||
}) {
|
||||
if steps > 0 {
|
||||
@ -727,7 +744,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let real_trait_pred_and_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(
|
||||
param_env,
|
||||
obligation.param_env,
|
||||
real_trait_pred_and_base_ty,
|
||||
);
|
||||
if self.predicate_may_hold(&obligation) {
|
||||
@ -855,6 +872,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
_ => return false,
|
||||
};
|
||||
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
|
||||
// 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()
|
||||
{
|
||||
&parent_code
|
||||
} else if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() {
|
||||
} else if let ObligationCauseCode::ItemObligation(_)
|
||||
| ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
|
||||
{
|
||||
obligation.cause.code()
|
||||
} else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) =
|
||||
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;
|
||||
|
||||
// Try to apply the original trait binding obligation by borrowing.
|
||||
let mut try_borrowing =
|
||||
|old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool {
|
||||
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| {
|
||||
(
|
||||
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| {
|
||||
(
|
||||
trait_pred,
|
||||
self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
|
||||
)
|
||||
});
|
||||
let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
blacklist: &[DefId]|
|
||||
-> bool {
|
||||
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| {
|
||||
(
|
||||
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| {
|
||||
(
|
||||
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 obligation =
|
||||
self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
|
||||
self.predicate_must_hold_modulo_regions(&obligation)
|
||||
};
|
||||
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 mk_result = |trait_pred_and_new_ty| {
|
||||
let obligation =
|
||||
self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
|
||||
self.predicate_must_hold_modulo_regions(&obligation)
|
||||
};
|
||||
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 (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
|
||||
if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code()
|
||||
let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
|
||||
if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
|
||||
&& 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)
|
||||
};
|
||||
|
||||
if imm_ref_self_ty_satisfies_pred
|
||||
|| mut_ref_self_ty_satisfies_pred
|
||||
|| ref_inner_ty_satisfies_pred
|
||||
{
|
||||
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
|
||||
// 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)];
|
||||
}
|
||||
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 imm_ref_self_ty_satisfies_pred
|
||||
|| mut_ref_self_ty_satisfies_pred
|
||||
|| ref_inner_ty_satisfies_pred
|
||||
{
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
// We don't want a borrowing suggestion on the fields in structs,
|
||||
// ```
|
||||
// struct Foo {
|
||||
// the_foos: Vec<Foo>
|
||||
// }
|
||||
// ```
|
||||
if !matches!(
|
||||
span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
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 {
|
||||
try_borrowing(cause.derived.parent_trait_pred, &[])
|
||||
} else if let ObligationCauseCode::BindingObligation(_, _)
|
||||
| ObligationCauseCode::ItemObligation(..) = code
|
||||
| ObligationCauseCode::ItemObligation(_)
|
||||
| ObligationCauseCode::ExprItemObligation(..)
|
||||
| ObligationCauseCode::ExprBindingObligation(..) = code
|
||||
{
|
||||
try_borrowing(poly_trait_pred, &never_suggest_borrow)
|
||||
} else {
|
||||
@ -2244,11 +2267,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
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
|
||||
// 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 mut multispan = MultiSpan::from(span);
|
||||
if let Some(ident) = tcx.opt_item_ident(item_def_id) {
|
||||
|
@ -117,11 +117,21 @@ pub enum TraitQueryMode {
|
||||
|
||||
/// Creates predicate obligations from the generic bounds.
|
||||
pub fn predicates_for_generics<'tcx>(
|
||||
cause: ObligationCause<'tcx>,
|
||||
cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
generic_bounds: ty::InstantiatedPredicates<'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
|
||||
|
@ -11,8 +11,6 @@ use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable
|
||||
use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
|
||||
pub use rustc_infer::traits::{self, util::*};
|
||||
|
||||
use std::iter;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// `TraitAliasExpander` iterator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -210,7 +208,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
|
||||
let Normalized { value: predicates, obligations: normalization_obligations2 } =
|
||||
super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
|
||||
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
|
||||
.chain(normalization_obligations1.into_iter())
|
||||
@ -219,27 +217,6 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
|
||||
(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>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
|
@ -711,7 +711,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
|
||||
.map(|((mut pred, span), origin_def_id)| {
|
||||
let code = if span.is_dummy() {
|
||||
traits::MiscObligation
|
||||
traits::ItemObligation(origin_def_id)
|
||||
} else {
|
||||
traits::BindingObligation(origin_def_id, span)
|
||||
};
|
||||
|
@ -1463,7 +1463,7 @@ pub fn check_type_bounds<'tcx>(
|
||||
);
|
||||
let mk_cause = |span: Span| {
|
||||
let code = if span.is_dummy() {
|
||||
traits::MiscObligation
|
||||
traits::ItemObligation(trait_ty.def_id)
|
||||
} else {
|
||||
traits::BindingObligation(trait_ty.def_id, span)
|
||||
};
|
||||
|
@ -607,9 +607,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
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() {
|
||||
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
|
||||
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);
|
||||
if !result.is_empty() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -820,23 +822,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ty = item_ty.subst(self.tcx, substs);
|
||||
|
||||
self.write_resolution(hir_id, Ok((def_kind, def_id)));
|
||||
self.add_required_obligations_with_code(
|
||||
span,
|
||||
def_id,
|
||||
&substs,
|
||||
match lang_item {
|
||||
hir::LangItem::IntoFutureIntoFuture => {
|
||||
ObligationCauseCode::AwaitableExpr(expr_hir_id)
|
||||
}
|
||||
hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
|
||||
ObligationCauseCode::ForLoopIterator
|
||||
}
|
||||
hir::LangItem::TryTraitFromOutput
|
||||
| hir::LangItem::TryTraitFromResidual
|
||||
| hir::LangItem::TryTraitBranch => ObligationCauseCode::QuestionMark,
|
||||
_ => traits::ItemObligation(def_id),
|
||||
},
|
||||
);
|
||||
|
||||
let code = match lang_item {
|
||||
hir::LangItem::IntoFutureIntoFuture => {
|
||||
Some(ObligationCauseCode::AwaitableExpr(expr_hir_id))
|
||||
}
|
||||
hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
|
||||
Some(ObligationCauseCode::ForLoopIterator)
|
||||
}
|
||||
hir::LangItem::TryTraitFromOutput
|
||||
| hir::LangItem::TryTraitFromResidual
|
||||
| hir::LangItem::TryTraitBranch => Some(ObligationCauseCode::QuestionMark),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(code) = code {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1348,7 +1352,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// First, store the "user substs" for later.
|
||||
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
|
||||
// the referenced item.
|
||||
@ -1385,32 +1389,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// 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,
|
||||
span: Span,
|
||||
def_id: DefId,
|
||||
substs: &SubstsRef<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
hir_id: hir::HirId,
|
||||
) {
|
||||
self.add_required_obligations_with_code(
|
||||
span,
|
||||
def_id,
|
||||
substs,
|
||||
traits::ItemObligation(def_id),
|
||||
)
|
||||
self.add_required_obligations_with_code(span, def_id, substs, |idx, span| {
|
||||
if span.is_dummy() {
|
||||
ObligationCauseCode::ExprItemObligation(def_id, hir_id, idx)
|
||||
} else {
|
||||
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(
|
||||
&self,
|
||||
span: Span,
|
||||
def_id: DefId,
|
||||
substs: &SubstsRef<'tcx>,
|
||||
code: ObligationCauseCode<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
|
||||
) {
|
||||
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
|
||||
|
||||
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,
|
||||
bounds,
|
||||
) {
|
||||
|
@ -15,6 +15,7 @@ use crate::check::{
|
||||
use crate::structured_errors::StructuredDiagnostic;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
@ -27,13 +28,14 @@ use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::TypeTrace;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
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_span::symbol::Ident;
|
||||
use rustc_span::{self, Span};
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
|
||||
|
||||
use std::iter;
|
||||
use std::ops::ControlFlow;
|
||||
use std::slice;
|
||||
|
||||
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
|
||||
// argument and not the call. This lets us customize the span pointed to in the
|
||||
// fulfillment error to be more accurate.
|
||||
let 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 coerced_ty = self.resolve_vars_with_obligations(coerced_ty);
|
||||
|
||||
let coerce_error = self
|
||||
.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
|
||||
// the call. This helps coercions.
|
||||
if check_closures {
|
||||
self.select_obligations_where_possible(false, |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,
|
||||
);
|
||||
})
|
||||
self.select_obligations_where_possible(false, |_| {})
|
||||
}
|
||||
|
||||
// Check each argument, to satisfy the input it was provided for
|
||||
@ -674,7 +657,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
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();
|
||||
return;
|
||||
}
|
||||
@ -1081,8 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
let suggestion_text = if let Some(provided_idx) = provided_idx
|
||||
&& let (_, provided_span) = provided_arg_tys[*provided_idx]
|
||||
&& let Ok(arg_text) =
|
||||
source_map.span_to_snippet(provided_span)
|
||||
&& let Ok(arg_text) = source_map.span_to_snippet(provided_span)
|
||||
{
|
||||
arg_text
|
||||
} else {
|
||||
@ -1183,7 +1171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
|
||||
|
||||
// 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))
|
||||
} 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
|
||||
/// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
|
||||
/// 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
|
||||
/// for either checked or coerced type, and there's only *one* argument that does, we point at
|
||||
/// the corresponding argument's expression span instead of the `fn` call path span.
|
||||
fn point_at_arg_instead_of_call_if_possible(
|
||||
/// Given a vector of fulfillment errors, try to adjust the spans of the
|
||||
/// errors to more accurately point at the cause of the failure.
|
||||
///
|
||||
/// This applies to calls, methods, and struct expressions. This will also
|
||||
/// try to deduplicate errors that are due to the same cause but might
|
||||
/// have been created with different [`ObligationCause`][traits::ObligationCause]s.
|
||||
pub(super) fn adjust_fulfillment_errors_for_expr_obligation(
|
||||
&self,
|
||||
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
|
||||
// the `?` operator.
|
||||
if call_sp.desugaring_kind().is_some() {
|
||||
return;
|
||||
// Store a mapping from `(Span, Predicate) -> ObligationCause`, so that
|
||||
// other errors that have the same span and predicate can also get fixed,
|
||||
// even if their `ObligationCauseCode` isn't an `Expr*Obligation` kind.
|
||||
// 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 {
|
||||
// Only if the cause is somewhere inside the expression we want try to point at arg.
|
||||
// Otherwise, it means that the cause is somewhere else and we should not change
|
||||
// anything because we can break the correct span.
|
||||
if !call_sp.contains(error.obligation.cause.span) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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() {
|
||||
for error in not_adjusted {
|
||||
for (span, predicate, cause) in &remap_cause {
|
||||
if *predicate == error.obligation.predicate
|
||||
&& span.contains(error.obligation.cause.span)
|
||||
{
|
||||
error.obligation.cause = cause.clone();
|
||||
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
|
||||
/// `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(
|
||||
fn adjust_fulfillment_error_for_expr_obligation(
|
||||
&self,
|
||||
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
||||
call_expr: &'tcx hir::Expr<'tcx>,
|
||||
) {
|
||||
if let hir::ExprKind::Call(path, _) = &call_expr.kind {
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind {
|
||||
for error in errors {
|
||||
let self_ty = match error.obligation.predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(predicate) => predicate.self_ty(),
|
||||
ty::PredicateKind::Projection(predicate) => {
|
||||
predicate.projection_ty.self_ty()
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
// If any of the type arguments in this path segment caused the
|
||||
// `FulfillmentError`, point at its span (#61860).
|
||||
for arg in path
|
||||
.segments
|
||||
.iter()
|
||||
.filter_map(|seg| seg.args.as_ref())
|
||||
.flat_map(|a| a.args.iter())
|
||||
error: &mut traits::FulfillmentError<'tcx>,
|
||||
) -> bool {
|
||||
let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx))
|
||||
= *error.obligation.cause.code().peel_derives() else { return false; };
|
||||
let hir = self.tcx.hir();
|
||||
let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; };
|
||||
|
||||
// Skip over mentioning async lang item
|
||||
if Some(def_id) == self.tcx.lang_items().from_generator_fn()
|
||||
&& error.obligation.cause.span.desugaring_kind()
|
||||
== Some(rustc_span::DesugaringKind::Async)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let Some(unsubstituted_pred) =
|
||||
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx)
|
||||
else { return false; };
|
||||
|
||||
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
|
||||
&& let Some(ty) =
|
||||
self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
|
||||
&& self.resolve_vars_if_possible(ty) == self_ty
|
||||
Some(arg)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// 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;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 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(
|
||||
@ -1864,14 +2075,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let new_def_id = self.probe(|_| {
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
call_kind.to_def_id(self.tcx),
|
||||
self.tcx.mk_substs([
|
||||
ty::GenericArg::from(callee_ty),
|
||||
self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: rustc_span::DUMMY_SP,
|
||||
})
|
||||
.into(),
|
||||
].into_iter()),
|
||||
self.tcx.mk_substs(
|
||||
[
|
||||
ty::GenericArg::from(callee_ty),
|
||||
self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: rustc_span::DUMMY_SP,
|
||||
})
|
||||
.into(),
|
||||
]
|
||||
.into_iter(),
|
||||
),
|
||||
);
|
||||
let obligation = traits::Obligation::new(
|
||||
traits::ObligationCause::dummy(),
|
||||
@ -1886,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
|
||||
Some(impl_source.impl_def_id)
|
||||
}
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
});
|
||||
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
|
||||
}
|
||||
|
@ -491,7 +491,19 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
// so we just call `predicates_for_generics` directly to avoid redoing work.
|
||||
// `self.add_required_obligations(self.span, def_id, &all_substs);`
|
||||
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,
|
||||
method_predicates,
|
||||
) {
|
||||
|
@ -534,7 +534,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
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.
|
||||
let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig));
|
||||
|
@ -1514,8 +1514,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds);
|
||||
|
||||
// Convert the bounds into obligations.
|
||||
let impl_obligations =
|
||||
traits::predicates_for_generics(cause, self.param_env, impl_bounds);
|
||||
let impl_obligations = traits::predicates_for_generics(
|
||||
move |_, _| cause.clone(),
|
||||
self.param_env,
|
||||
impl_bounds,
|
||||
);
|
||||
|
||||
let candidate_obligations = impl_obligations
|
||||
.chain(norm_obligations.into_iter())
|
||||
|
@ -36,9 +36,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
|
||||
--> $DIR/associated-types-eq-3.rs:40:9
|
||||
|
|
||||
LL | baz(&a);
|
||||
| --- ^^ type mismatch resolving `<isize as Foo>::A == Bar`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^ type mismatch resolving `<isize as Foo>::A == Bar`
|
||||
|
|
||||
note: expected this to be `Bar`
|
||||
--> $DIR/associated-types-eq-3.rs:12:14
|
||||
|
@ -17,10 +17,12 @@ LL | f1(2i32, 4u32);
|
||||
| ~~~
|
||||
|
||||
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);
|
||||
| ^^ 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`
|
||||
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
|
||||
|
|
||||
LL | f1(2u32, 4u32);
|
||||
| -- ^^^^ the trait `Foo` is not implemented for `u32`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^ the trait `Foo` is not implemented for `u32`
|
||||
|
|
||||
= help: the trait `Foo` is implemented for `i32`
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
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)
|
||||
| ------------------------- ^ the trait `Copy` is not implemented for `T`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
||||
|
|
||||
note: required by a bound in `copy`
|
||||
--> $DIR/issue-27675-unchecked-bounds.rs:10:12
|
||||
|
@ -1,8 +1,12 @@
|
||||
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 {
|
||||
| ^^^^^ future created by async block is not `Send`
|
||||
LL | spawn(async {
|
||||
| ___________^
|
||||
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 ()`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
|
@ -1,8 +1,8 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^^ 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>`
|
||||
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`
|
||||
|
||||
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);
|
||||
| ^^^^^^^^^^^^ 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>`
|
||||
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`
|
||||
|
||||
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);
|
||||
| ^^^^^^^^^^^^ `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>`
|
||||
= note: required for `Arc<RefCell<i32>>` to implement `Send`
|
||||
|
@ -1,8 +1,12 @@
|
||||
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 {
|
||||
| ^^^^^^^^^^^ future created by async block is not `Send`
|
||||
LL | assert_send(async {
|
||||
| _________________^
|
||||
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`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
|
@ -1,8 +1,8 @@
|
||||
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)>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 by a bound in `is_mytrait`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
|
||||
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
|
||||
|
|
||||
= help: the trait `Signed` is implemented for `i32`
|
||||
note: required for `&'static u32` to implement `Defaulted`
|
||||
|
@ -15,8 +15,8 @@ fn main() {
|
||||
x: 5,
|
||||
};
|
||||
|
||||
let s = S { //~ ERROR the trait bound `{float}: Foo` is not satisfied
|
||||
x: 5.0,
|
||||
let s = S {
|
||||
x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied
|
||||
};
|
||||
|
||||
let s = S {
|
||||
|
@ -1,8 +1,8 @@
|
||||
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 {
|
||||
| ^ the trait `Foo` is not implemented for `{float}`
|
||||
LL | x: 5.0,
|
||||
| ^^^ the trait `Foo` is not implemented for `{float}`
|
||||
|
|
||||
= help: the trait `Foo` is implemented for `i32`
|
||||
note: required by a bound in `S`
|
||||
|
@ -8,6 +8,8 @@ LL | num += 1;
|
||||
...
|
||||
LL | Box::new(closure)
|
||||
| ----------------- 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
|
||||
|
||||
|
@ -8,6 +8,8 @@ LL | vec
|
||||
...
|
||||
LL | Box::new(closure)
|
||||
| ----------------- 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
|
||||
|
||||
|
@ -7,7 +7,15 @@ LL | let [_, _s] = s;
|
||||
| - closure is `FnOnce` because it moves the variable `s` out of its environment
|
||||
LL | };
|
||||
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
|
||||
|
||||
|
@ -7,7 +7,15 @@ LL | let s = s.1;
|
||||
| --- closure is `FnOnce` because it moves the variable `s.1` out of its environment
|
||||
LL | };
|
||||
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
|
||||
|
||||
|
@ -1,8 +1,14 @@
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
|
||||
LL | let t = thread::spawn(|| {
|
||||
| _____________-------------_^
|
||||
| | |
|
||||
| | 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<()>`
|
||||
= note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send`
|
||||
@ -18,10 +24,12 @@ LL | F: Send + 'static,
|
||||
| ^^^^ required by this bound in `spawn`
|
||||
|
||||
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());
|
||||
| ^^^^^^^^^^^^^ `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<()>`
|
||||
= note: required for `&Sender<()>` to implement `Send`
|
||||
|
@ -6,7 +6,15 @@ LL | let closure = |_| foo(x);
|
||||
| |
|
||||
| this closure implements `FnOnce`, not `Fn`
|
||||
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
|
||||
|
||||
|
@ -2,9 +2,7 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied
|
||||
--> $DIR/trait_objects_fail.rs:26:9
|
||||
|
|
||||
LL | foo(&10_u32);
|
||||
| --- ^^^^^^^ the trait `Trait` is not implemented for `u32`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^^^^ the trait `Trait` is not 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`
|
||||
@ -13,9 +11,7 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
|
||||
--> $DIR/trait_objects_fail.rs:28:9
|
||||
|
|
||||
LL | bar(&true);
|
||||
| --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^^ the trait `Traitor<_>` is not 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<_>`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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`
|
||||
@ -26,10 +26,10 @@ LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
found type `{ O as u128 }`
|
||||
|
||||
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 _ }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
|
||||
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
|
||||
@ -71,10 +71,10 @@ LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||
found type `14`
|
||||
|
||||
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 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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`
|
||||
@ -98,10 +98,10 @@ LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
found type `{ O as u128 }`
|
||||
|
||||
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 _ }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
|
||||
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
|
||||
|
@ -2,7 +2,7 @@ error[E0277]: can't drop `UnconstDrop` in const contexts
|
||||
--> $DIR/const-block-const-bound.rs:20:11
|
||||
|
|
||||
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
|
||||
|
|
||||
@ -23,7 +23,7 @@ error[E0277]: can't drop `NonDrop` in const contexts
|
||||
--> $DIR/const-block-const-bound.rs:22:11
|
||||
|
|
||||
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
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `B<C>: Copy` is not satisfied
|
||||
--> $DIR/deriving-copyclone.rs:31:13
|
||||
|
|
||||
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
|
||||
|
|
||||
@ -26,7 +26,7 @@ error[E0277]: the trait bound `B<C>: Clone` is not satisfied
|
||||
--> $DIR/deriving-copyclone.rs:32:14
|
||||
|
|
||||
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
|
||||
|
|
||||
@ -50,7 +50,7 @@ error[E0277]: the trait bound `B<D>: Copy` is not satisfied
|
||||
--> $DIR/deriving-copyclone.rs:35:13
|
||||
|
|
||||
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
|
||||
|
|
||||
|
@ -1,8 +1,10 @@
|
||||
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);
|
||||
| ^^^ 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>`:
|
||||
<Bar as Foo<i32>>
|
||||
|
@ -1,8 +1,10 @@
|
||||
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);
|
||||
| ^^^ 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>`:
|
||||
<Bar as Foo<i16>>
|
||||
|
@ -1,8 +1,8 @@
|
||||
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>();
|
||||
| ^^^^^^^^^^^^^^ `*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`
|
||||
note: required because it appears within the type `Baz`
|
||||
|
12
src/test/ui/extern/extern-types-unsized.stderr
vendored
12
src/test/ui/extern/extern-types-unsized.stderr
vendored
@ -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
|
||||
--> $DIR/extern-types-unsized.rs:25:5
|
||||
--> $DIR/extern-types-unsized.rs:25:20
|
||||
|
|
||||
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`
|
||||
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
|
||||
--> $DIR/extern-types-unsized.rs:28:5
|
||||
--> $DIR/extern-types-unsized.rs:28:20
|
||||
|
|
||||
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`
|
||||
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
|
||||
--> $DIR/extern-types-unsized.rs:31:5
|
||||
--> $DIR/extern-types-unsized.rs:31:20
|
||||
|
|
||||
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`
|
||||
note: required because it appears within the type `Bar<A>`
|
||||
|
@ -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
|
||||
|
|
||||
LL | foo(*x);
|
||||
| --- ^^ doesn't have a size known at compile-time
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
|
@ -1,8 +1,10 @@
|
||||
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));
|
||||
| ^^^^ `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`
|
||||
= 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`
|
||||
|
||||
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));
|
||||
| ^^^^ `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`
|
||||
= note: required because it appears within the type `&core::fmt::Opaque`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
| ^ generator is not `Send`
|
||||
...
|
||||
LL | / type_combinations!(
|
||||
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)
|
||||
|
||||
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);
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
| ^ generator is not `Send`
|
||||
...
|
||||
LL | / type_combinations!(
|
||||
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)
|
||||
|
||||
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);
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
| ^ generator is not `Send`
|
||||
...
|
||||
LL | / type_combinations!(
|
||||
LL | | // OK
|
||||
|
@ -1,8 +1,14 @@
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
LL | assert_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`
|
||||
note: generator is not `Send` as this value is used across a yield
|
||||
|
@ -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]`
|
||||
--> $DIR/generator-yielding-or-returning-itself.rs:15:5
|
||||
--> $DIR/generator-yielding-or-returning-itself.rs:15:34
|
||||
|
|
||||
LL | want_cyclic_generator_return(|| {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
|
||||
LL | want_cyclic_generator_return(|| {
|
||||
| _____----------------------------_^
|
||||
| | |
|
||||
| | 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;
|
||||
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`
|
||||
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
|
||||
LL | want_cyclic_generator_yield(|| {
|
||||
| _____---------------------------_^
|
||||
| | |
|
||||
| | 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;
|
||||
this error may be the result of a recent compiler bug-fix,
|
||||
|
@ -64,6 +64,7 @@ fn test2() {
|
||||
//~^ ERROR `RefCell<i32>` cannot be shared between threads safely
|
||||
//~| NOTE `RefCell<i32>` cannot be shared between threads safely
|
||||
//~| NOTE required for
|
||||
//~| NOTE required by a bound introduced by this call
|
||||
//~| NOTE captures the following types
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^^ generator is not `Send`
|
||||
| ^^^^^^^^ generator is not `Send`
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||
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`
|
||||
|
||||
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);
|
||||
| ^^^^^^^^^^^^ `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>`
|
||||
= note: required for `Arc<RefCell<i32>>` to implement `Send`
|
||||
|
@ -1,8 +1,15 @@
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
|
||||
LL | assert_send(|| {
|
||||
| _____-----------_^
|
||||
| | |
|
||||
| | 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>`
|
||||
= 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`
|
||||
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^ generator is not `Sync`
|
||||
LL | assert_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>`
|
||||
note: generator is not `Sync` as this value is used across a yield
|
||||
|
@ -1,8 +1,15 @@
|
||||
error: generator cannot be sent between threads safely
|
||||
--> $DIR/partial-drop.rs:14:5
|
||||
--> $DIR/partial-drop.rs:14:17
|
||||
|
|
||||
LL | assert_send(|| {
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
LL | assert_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`
|
||||
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`
|
||||
|
||||
error: generator cannot be sent between threads safely
|
||||
--> $DIR/partial-drop.rs:22:5
|
||||
--> $DIR/partial-drop.rs:22:17
|
||||
|
|
||||
LL | assert_send(|| {
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
LL | assert_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`
|
||||
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`
|
||||
|
||||
error: generator cannot be sent between threads safely
|
||||
--> $DIR/partial-drop.rs:32:5
|
||||
--> $DIR/partial-drop.rs:32:17
|
||||
|
|
||||
LL | assert_send(|| {
|
||||
| ^^^^^^^^^^^ generator is not `Send`
|
||||
LL | assert_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`
|
||||
note: generator is not `Send` as this value is used across a yield
|
||||
|
@ -1,8 +1,8 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^^ generator is not `Send`
|
||||
| ^^^^^^^^ generator is not `Send`
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||
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`
|
||||
|
||||
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);
|
||||
| ^^^^^^^^^^^^ `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>`
|
||||
= note: required for `Arc<RefCell<i32>>` to implement `Send`
|
||||
|
@ -1,8 +1,15 @@
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
|
||||
LL | assert_send(|| {
|
||||
| _____-----------_^
|
||||
| | |
|
||||
| | 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>`
|
||||
= 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`
|
||||
|
||||
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(|| {
|
||||
| ^^^^^^^^^^^ generator is not `Sync`
|
||||
LL | assert_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>`
|
||||
note: generator is not `Sync` as this value is used across a yield
|
||||
|
@ -1,8 +1,10 @@
|
||||
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);
|
||||
| ^^^^ 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 `()`
|
||||
note: required by a bound in `test`
|
||||
|
@ -1,8 +1,10 @@
|
||||
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, ());
|
||||
| ^^^^ 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 `((),)`
|
||||
found a closure with arguments `(<_ as ATC<'a>>::Type,)`
|
||||
|
@ -2,7 +2,9 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-71732.rs:18:10
|
||||
|
|
||||
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`:
|
||||
- impl Borrow<str> for String;
|
||||
@ -13,7 +15,7 @@ note: required by a bound in `HashMap::<K, V, S>::get`
|
||||
|
|
||||
LL | K: Borrow<Q>,
|
||||
| ^^^^^^^^^ 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())
|
||||
| +++++
|
||||
|
@ -4,7 +4,7 @@ error[E0283]: type annotations needed
|
||||
LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
|
||||
| --- ^^^ 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: required by a bound in `foo`
|
||||
|
@ -4,7 +4,7 @@ error[E0283]: type annotations needed
|
||||
LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
|
||||
| -------- ^^^ 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: required by a bound in `Foo::bar`
|
||||
|
@ -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
|
||||
--> $DIR/interior-mutability.rs:5:5
|
||||
--> $DIR/interior-mutability.rs:5:18
|
||||
|
|
||||
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>`
|
||||
= note: required because it appears within the type `Cell<i32>`
|
||||
|
@ -1,8 +1,10 @@
|
||||
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();
|
||||
| ^^^^ 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`
|
||||
--> $SRC_DIR/alloc/src/slice.rs:LL:COL
|
||||
|
@ -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
|
||||
|
|
||||
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: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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<()>>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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<()>`
|
||||
= note: required because it appears within the type `(Rc<()>, Rc<()>)`
|
||||
|
@ -4,12 +4,12 @@ pub fn get_tok(it: &mut IntoIter<u8>) {
|
||||
let mut found_e = false;
|
||||
|
||||
let temp: Vec<u8> = it
|
||||
//~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
|
||||
.take_while(|&x| {
|
||||
found_e = true;
|
||||
false
|
||||
})
|
||||
.cloned()
|
||||
//~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
|
||||
.collect(); //~ ERROR the method
|
||||
}
|
||||
|
||||
|
@ -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`
|
||||
--> $DIR/issue-31173.rs:11:10
|
||||
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:6:25
|
||||
|
|
||||
LL | .cloned()
|
||||
| ^^^^^^ expected reference, found `u8`
|
||||
LL | let temp: Vec<u8> = it
|
||||
| _________________________^
|
||||
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 `&_`
|
||||
found type `u8`
|
||||
@ -12,11 +20,11 @@ note: required by a bound in `cloned`
|
||||
LL | Self: Sized + Iterator<Item = &'a T>,
|
||||
| ^^^^^^^^^^^^ 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
|
||||
|
|
||||
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
|
||||
|
|
||||
@ -29,10 +37,10 @@ LL | pub struct Cloned<I> {
|
||||
| -------------------- doesn't satisfy `_: Iterator`
|
||||
|
|
||||
= 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 = &_`
|
||||
which is required by `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:7:21: 7:25]>>: Iterator`
|
||||
which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
|
||||
`<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:8:21: 8: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:8:21: 8:25]>>: Iterator`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
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() {}
|
||||
| ^^^^^^ expected reference, found tuple
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call
|
||||
| |
|
||||
| expected reference, found tuple
|
||||
|
|
||||
= note: expected reference `&_`
|
||||
found tuple `(&_, &_)`
|
||||
|
@ -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 `()`
|
||||
--> $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();
|
||||
| ^^^^^^^ 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<T>` is implemented for `Vec<T>`
|
||||
|
@ -7,7 +7,15 @@ LL | farewell.push_str("!!!");
|
||||
| -------- closure is `FnMut` because it mutates the variable `farewell` here
|
||||
...
|
||||
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
|
||||
|
||||
|
@ -30,4 +30,5 @@ fn main() {
|
||||
assert_eq!(Foo::Bar, i);
|
||||
//~^ 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]
|
||||
}
|
||||
|
@ -106,7 +106,26 @@ LL | assert_eq!(Foo::Bar, i);
|
||||
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 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.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -1,8 +1,8 @@
|
||||
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)
|
||||
| ------------- ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32`
|
||||
| ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -1,8 +1,10 @@
|
||||
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();
|
||||
| ^^^^^^^ 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<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`
|
||||
|
||||
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>>();
|
||||
| ^^^^^^^ 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<T>` is implemented for `Vec<T>`
|
||||
|
@ -16,7 +16,7 @@ error[E0283]: type annotations needed
|
||||
LL | println!("{}", 23u64.test(xs.iter().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
|
||||
--> $DIR/issue-69455.rs:11:1
|
||||
|
@ -4,4 +4,5 @@ fn main() {
|
||||
//~^ 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 required by a bound in `collect`
|
||||
//~| NOTE required by a bound introduced by this call
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
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();
|
||||
| ^^^^^^^ 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]`
|
||||
note: required by a bound in `collect`
|
||||
|
@ -1,15 +1,20 @@
|
||||
fn process_slice(data: &[i32]) {
|
||||
//~^ NOTE required by a bound in this
|
||||
//~| NOTE required by a bound in this
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
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 a slice of type `[i32]` cannot be built since `[i32]` has no definite size
|
||||
//~| NOTE try explicitly collecting into a `Vec<{integer}>`
|
||||
//~| 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 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);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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();
|
||||
| ^^^^^^^^^^^^^^^^^^ 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
|
||||
= 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
|
||||
--> $DIR/collect-into-slice.rs:7:38
|
||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||
--> $DIR/collect-into-slice.rs:8:38
|
||||
|
|
||||
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]`
|
||||
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
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ 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`.
|
||||
|
@ -11,5 +11,5 @@ fn take_param<T:Foo>(foo: &T) { }
|
||||
fn main() {
|
||||
let x: Box<_> = Box::new(3);
|
||||
take_param(&x);
|
||||
//~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied
|
||||
//~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied
|
||||
}
|
||||
|
@ -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
|
||||
|
|
||||
LL | take_param(&x);
|
||||
|
@ -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
|
||||
|
|
||||
LL | take_param(&x);
|
||||
|
@ -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
|
||||
|
|
||||
LL | take_param(&x);
|
||||
|
@ -1,10 +1,12 @@
|
||||
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));
|
||||
| ^^^ ------ 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>`
|
||||
note: required because it's used within this closure
|
||||
|
@ -1,8 +1,8 @@
|
||||
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)>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(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)`
|
||||
= 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`
|
||||
|
||||
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>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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`
|
||||
= note: required for `Unique<dyn Dummy>` to implement `Send`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(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)`
|
||||
= 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`
|
||||
|
||||
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>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(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)`
|
||||
= note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(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)`
|
||||
= 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`
|
||||
|
||||
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>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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`
|
||||
= note: required for `Unique<dyn Dummy>` to implement `Send`
|
||||
|
@ -1,8 +1,8 @@
|
||||
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>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*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`
|
||||
= note: required for `Unique<*mut u8>` to implement `Send`
|
||||
|
@ -1,8 +1,10 @@
|
||||
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()
|
||||
| ^^^^^^^ 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`
|
||||
note: required by a bound in `collect`
|
||||
|
@ -1,8 +1,10 @@
|
||||
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();
|
||||
| ^^^^^^^ 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`
|
||||
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`
|
||||
|
||||
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();
|
||||
| ^^^^^^^ 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`
|
||||
note: required by a bound in `collect`
|
||||
|
@ -1,8 +1,10 @@
|
||||
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();
|
||||
| ^^^^^^ `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`
|
||||
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
|
||||
|
@ -1,8 +1,10 @@
|
||||
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);
|
||||
| ^^^ 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 `()`
|
||||
= 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)
|
||||
|
@ -32,6 +32,7 @@ fn smeg() {
|
||||
//[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
|
||||
//[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()`
|
||||
//[fallback]~| NOTE this error might have been caused
|
||||
//[fallback]~| NOTE required by a bound introduced by this call
|
||||
//[fallback]~| HELP did you intend
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^^^^^^^ 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`:
|
||||
()
|
||||
|
@ -1,8 +1,12 @@
|
||||
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!())
|
||||
| ^^^ 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`
|
||||
--> $DIR/feature-gate-never_type_fallback.rs:13:16
|
||||
|
@ -1,8 +1,10 @@
|
||||
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);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ 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`
|
||||
|
||||
|
@ -1,10 +1,17 @@
|
||||
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|| {
|
||||
| ^^^^^^^^^^^^^ ------ within this `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`
|
||||
| |
|
||||
| `Rc<()>` cannot be sent between threads safely
|
||||
LL | thread::spawn(move|| {
|
||||
| ------------- ^-----
|
||||
| | |
|
||||
| _____|_____________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<()>`
|
||||
note: required because it appears within the type `Port<()>`
|
||||
|
@ -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]`
|
||||
--> $DIR/not-clone-closure.rs:11:23
|
||||
--> $DIR/not-clone-closure.rs:11:17
|
||||
|
|
||||
LL | let hello = move || {
|
||||
| ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
|
||||
...
|
||||
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
|
||||
--> $DIR/not-clone-closure.rs:7:17
|
||||
|
@ -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
|
||||
--> $DIR/not-panic-safe-2.rs:10:5
|
||||
--> $DIR/not-panic-safe-2.rs:10:14
|
||||
|
|
||||
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>`
|
||||
= 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`
|
||||
|
||||
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>>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>`
|
||||
= note: required because it appears within the type `Cell<isize>`
|
||||
|
@ -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
|
||||
--> $DIR/not-panic-safe-3.rs:10:5
|
||||
--> $DIR/not-panic-safe-3.rs:10:14
|
||||
|
|
||||
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>`
|
||||
= 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`
|
||||
|
||||
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>>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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>`
|
||||
= 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
Loading…
Reference in New Issue
Block a user