1
Fork 0

Bless tests after #100769

This commit is contained in:
Michael Goulet 2022-08-21 03:52:08 +00:00
parent 5212ac9dac
commit d577eb09e5
2 changed files with 99 additions and 96 deletions

View file

@ -903,7 +903,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code() obligation.cause.code()
{ {
&parent_code &parent_code
} else if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() { } else if let ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
{
obligation.cause.code() obligation.cause.code()
} else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) = } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) =
span.ctxt().outer_expn_data().kind span.ctxt().outer_expn_data().kind
@ -929,35 +931,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let param_env = obligation.param_env; let param_env = obligation.param_env;
// Try to apply the original trait binding obligation by borrowing. // Try to apply the original trait binding obligation by borrowing.
let mut try_borrowing = let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
|old_pred: ty::PolyTraitPredicate<'tcx>, blacklist: &[DefId]| -> bool { blacklist: &[DefId]|
if blacklist.contains(&old_pred.def_id()) { -> bool {
return false; if blacklist.contains(&old_pred.def_id()) {
} return false;
// We map bounds to `&T` and `&mut T` }
let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| { // We map bounds to `&T` and `&mut T`
( let trait_pred_and_imm_ref = old_pred.map_bound(|trait_pred| {
trait_pred, (
self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), trait_pred,
) self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
}); )
let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| { });
( let trait_pred_and_mut_ref = old_pred.map_bound(|trait_pred| {
trait_pred, (
self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()), trait_pred,
) self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, trait_pred.self_ty()),
}); )
});
let mk_result = |trait_pred_and_new_ty| { let mk_result = |trait_pred_and_new_ty| {
let obligation = let obligation =
self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty); self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
self.predicate_must_hold_modulo_regions(&obligation) self.predicate_must_hold_modulo_regions(&obligation)
}; };
let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() if let ObligationCauseCode::ItemObligation(_) | ObligationCauseCode::ExprItemObligation(..) = obligation.cause.code()
&& let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind()
{ {
( (
@ -968,74 +971,74 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
(false, false) (false, false)
}; };
if imm_ref_self_ty_satisfies_pred if imm_ref_self_ty_satisfies_pred
|| mut_ref_self_ty_satisfies_pred || mut_ref_self_ty_satisfies_pred
|| ref_inner_ty_satisfies_pred || ref_inner_ty_satisfies_pred
{ {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
// We don't want a borrowing suggestion on the fields in structs, // We don't want a borrowing suggestion on the fields in structs,
// ``` // ```
// struct Foo { // struct Foo {
// the_foos: Vec<Foo> // the_foos: Vec<Foo>
// } // }
// ``` // ```
if !matches!( if !matches!(
span.ctxt().outer_expn_data().kind, span.ctxt().outer_expn_data().kind,
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
) { ) {
return false; 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;
} }
if snippet.starts_with('&') {
// This is already a literal borrow and the obligation is failing
// somewhere else in the obligation chain. Do not suggest non-sense.
return false;
}
// We have a very specific type of error, where just borrowing this argument
// might solve the problem. In cases like this, the important part is the
// original type obligation, not the last one that failed, which is arbitrary.
// Because of this, we modify the error to refer to the original obligation and
// return early in the caller.
let msg = format!("the trait bound `{}` is not satisfied", old_pred);
if has_custom_message {
err.note(&msg);
} else {
err.message =
vec![(rustc_errors::DiagnosticMessage::Str(msg), Style::NoStyle)];
}
err.span_label(
span,
format!(
"the trait `{}` is not implemented for `{}`",
old_pred.print_modifiers_and_trait_path(),
old_pred.self_ty().skip_binder(),
),
);
if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
err.span_suggestions(
span.shrink_to_lo(),
"consider borrowing here",
["&".to_string(), "&mut ".to_string()].into_iter(),
Applicability::MaybeIncorrect,
);
} else {
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!(
"consider{} borrowing here",
if is_mut { " mutably" } else { "" }
),
format!("&{}", if is_mut { "mut " } else { "" }),
Applicability::MaybeIncorrect,
);
}
return true;
} }
return false; }
}; return false;
};
if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code { if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code {
try_borrowing(cause.derived.parent_trait_pred, &[]) try_borrowing(cause.derived.parent_trait_pred, &[])

View file

@ -2,7 +2,7 @@ error[E0277]: the trait bound `&mut usize: Default` is not satisfied
--> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9 --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9
| |
LL | foo(Default::default()); LL | foo(Default::default());
| ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default` | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize`
| |
help: consider mutably borrowing here help: consider mutably borrowing here
| |
@ -13,7 +13,7 @@ error[E0277]: the trait bound `&usize: Default` is not satisfied
--> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9 --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9
| |
LL | bar(Default::default()); LL | bar(Default::default());
| ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default` | ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize`
| |
help: consider borrowing here help: consider borrowing here
| |