Rollup merge of #126142 - compiler-errors:trait-ref-split, r=jackh726
Harmonize using root or leaf obligation in trait error reporting When #121826 changed the error reporting to use root obligation and not the leafmost obligation, it didn't actually make sure that all the other diagnostics helper functions used the right obligation. Specifically, when reporting similar impl candidates we are looking for impls of the root obligation, but trying to match them against the trait ref of the leaf obligation. This does a few other miscellaneous changes. There's a lot more clean-up that could be done here, but working with this code is really grief-inducing due to how messy it has become over the years. Someone really needs to show it love. 😓 r? ``@estebank`` Fixes #126129
This commit is contained in:
commit
25c55c51cb
@ -546,7 +546,7 @@ fn suggest_constraint(
|
|||||||
for pred in hir_generics.bounds_for_param(def_id) {
|
for pred in hir_generics.bounds_for_param(def_id) {
|
||||||
if self.constrain_generic_bound_associated_type_structured_suggestion(
|
if self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
diag,
|
diag,
|
||||||
&trait_ref,
|
trait_ref,
|
||||||
pred.bounds,
|
pred.bounds,
|
||||||
assoc,
|
assoc,
|
||||||
assoc_args,
|
assoc_args,
|
||||||
@ -715,7 +715,7 @@ fn suggest_constraining_opaque_associated_type(
|
|||||||
|
|
||||||
self.constrain_generic_bound_associated_type_structured_suggestion(
|
self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
diag,
|
diag,
|
||||||
&trait_ref,
|
trait_ref,
|
||||||
opaque_hir_ty.bounds,
|
opaque_hir_ty.bounds,
|
||||||
assoc,
|
assoc,
|
||||||
assoc_args,
|
assoc_args,
|
||||||
@ -869,7 +869,7 @@ trait defining them",
|
|||||||
fn constrain_generic_bound_associated_type_structured_suggestion(
|
fn constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
&self,
|
&self,
|
||||||
diag: &mut Diag<'_>,
|
diag: &mut Diag<'_>,
|
||||||
trait_ref: &ty::TraitRef<'tcx>,
|
trait_ref: ty::TraitRef<'tcx>,
|
||||||
bounds: hir::GenericBounds<'_>,
|
bounds: hir::GenericBounds<'_>,
|
||||||
assoc: ty::AssocItem,
|
assoc: ty::AssocItem,
|
||||||
assoc_args: &[ty::GenericArg<'tcx>],
|
assoc_args: &[ty::GenericArg<'tcx>],
|
||||||
|
@ -285,8 +285,7 @@ fn elaborate(&mut self, elaboratable: &O) {
|
|||||||
let obligations =
|
let obligations =
|
||||||
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
|
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
|
||||||
elaboratable.child_with_derived_cause(
|
elaboratable.child_with_derived_cause(
|
||||||
clause
|
clause.instantiate_supertrait(tcx, bound_clause.rebind(data.trait_ref)),
|
||||||
.instantiate_supertrait(tcx, &bound_clause.rebind(data.trait_ref)),
|
|
||||||
span,
|
span,
|
||||||
bound_clause.rebind(data),
|
bound_clause.rebind(data),
|
||||||
index,
|
index,
|
||||||
|
@ -37,7 +37,7 @@ fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
|
|||||||
let super_predicates =
|
let super_predicates =
|
||||||
self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|
self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|
||||||
|&(pred, _)| {
|
|&(pred, _)| {
|
||||||
let clause = pred.instantiate_supertrait(self.tcx, &trait_ref);
|
let clause = pred.instantiate_supertrait(self.tcx, trait_ref);
|
||||||
self.visited.insert(clause).then_some(clause)
|
self.visited.insert(clause).then_some(clause)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -313,7 +313,7 @@ impl<'tcx> Clause<'tcx> {
|
|||||||
pub fn instantiate_supertrait(
|
pub fn instantiate_supertrait(
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) -> Clause<'tcx> {
|
) -> Clause<'tcx> {
|
||||||
// The interaction between HRTB and supertraits is not entirely
|
// The interaction between HRTB and supertraits is not entirely
|
||||||
// obvious. Let me walk you (and myself) through an example.
|
// obvious. Let me walk you (and myself) through an example.
|
||||||
|
@ -3597,7 +3597,7 @@ fn suggest_floating_point_literal(
|
|||||||
&self,
|
&self,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) {
|
) {
|
||||||
let rhs_span = match obligation.cause.code() {
|
let rhs_span = match obligation.cause.code() {
|
||||||
ObligationCauseCode::BinOp { rhs_span: Some(span), rhs_is_lit, .. } if *rhs_is_lit => {
|
ObligationCauseCode::BinOp { rhs_span: Some(span), rhs_is_lit, .. } if *rhs_is_lit => {
|
||||||
@ -4592,7 +4592,7 @@ fn suggest_add_result_as_return_type(
|
|||||||
&self,
|
&self,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
) {
|
) {
|
||||||
if ObligationCauseCode::QuestionMark != *obligation.cause.code().peel_derives() {
|
if ObligationCauseCode::QuestionMark != *obligation.cause.code().peel_derives() {
|
||||||
return;
|
return;
|
||||||
@ -4602,10 +4602,9 @@ fn suggest_add_result_as_return_type(
|
|||||||
if let hir::Node::Item(item) = node
|
if let hir::Node::Item(item) = node
|
||||||
&& let hir::ItemKind::Fn(sig, _, body_id) = item.kind
|
&& let hir::ItemKind::Fn(sig, _, body_id) = item.kind
|
||||||
&& let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output
|
&& let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output
|
||||||
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_ref.def_id())
|
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_pred.def_id())
|
||||||
&& let ty::Tuple(l) = trait_ref.skip_binder().args.type_at(0).kind()
|
&& trait_pred.skip_binder().trait_ref.args.type_at(0).is_unit()
|
||||||
&& l.len() == 0
|
&& let ty::Adt(def, _) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
|
||||||
&& let ty::Adt(def, _) = trait_ref.skip_binder().args.type_at(1).kind()
|
|
||||||
&& self.tcx.is_diagnostic_item(sym::Result, def.did())
|
&& self.tcx.is_diagnostic_item(sym::Result, def.did())
|
||||||
{
|
{
|
||||||
let body = self.tcx.hir().body(body_id);
|
let body = self.tcx.hir().body(body_id);
|
||||||
@ -4863,14 +4862,13 @@ fn visit_ty(&mut self, t: &'hir hir::Ty<'hir>) {
|
|||||||
pub(super) fn get_explanation_based_on_obligation<'tcx>(
|
pub(super) fn get_explanation_based_on_obligation<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_predicate: ty::PolyTraitPredicate<'tcx>,
|
||||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
|
||||||
pre_message: String,
|
pre_message: String,
|
||||||
) -> String {
|
) -> String {
|
||||||
if let ObligationCauseCode::MainFunctionType = obligation.cause.code() {
|
if let ObligationCauseCode::MainFunctionType = obligation.cause.code() {
|
||||||
"consider using `()`, or a `Result`".to_owned()
|
"consider using `()`, or a `Result`".to_owned()
|
||||||
} else {
|
} else {
|
||||||
let ty_desc = match trait_ref.skip_binder().self_ty().kind() {
|
let ty_desc = match trait_predicate.self_ty().skip_binder().kind() {
|
||||||
ty::FnDef(_, _) => Some("fn item"),
|
ty::FnDef(_, _) => Some("fn item"),
|
||||||
ty::Closure(_, _) => Some("closure"),
|
ty::Closure(_, _) => Some("closure"),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -4895,7 +4893,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
|
|||||||
format!(
|
format!(
|
||||||
"{pre_message}the trait `{}` is not implemented for{desc} `{}`{post}",
|
"{pre_message}the trait `{}` is not implemented for{desc} `{}`{post}",
|
||||||
trait_predicate.print_modifiers_and_trait_path(),
|
trait_predicate.print_modifiers_and_trait_path(),
|
||||||
tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None),
|
tcx.short_ty_string(trait_predicate.self_ty().skip_binder(), &mut None),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is
|
// "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is
|
||||||
|
@ -412,8 +412,8 @@ fn report_selection_error(
|
|||||||
let bound_predicate = obligation.predicate.kind();
|
let bound_predicate = obligation.predicate.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
||||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
let leaf_trait_predicate =
|
||||||
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
self.resolve_vars_if_possible(bound_predicate.rebind(trait_predicate));
|
||||||
|
|
||||||
// Let's use the root obligation as the main message, when we care about the
|
// Let's use the root obligation as the main message, when we care about the
|
||||||
// most general case ("X doesn't implement Pattern<'_>") over the case that
|
// most general case ("X doesn't implement Pattern<'_>") over the case that
|
||||||
@ -424,7 +424,7 @@ fn report_selection_error(
|
|||||||
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
|
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
|
||||||
ty::ClauseKind::Trait(root_pred)
|
ty::ClauseKind::Trait(root_pred)
|
||||||
) = root_obligation.predicate.kind().skip_binder()
|
) = root_obligation.predicate.kind().skip_binder()
|
||||||
&& !trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()
|
&& !leaf_trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()
|
||||||
&& !root_pred.self_ty().has_escaping_bound_vars()
|
&& !root_pred.self_ty().has_escaping_bound_vars()
|
||||||
// The type of the leaf predicate is (roughly) the same as the type
|
// The type of the leaf predicate is (roughly) the same as the type
|
||||||
// from the root predicate, as a proxy for "we care about the root"
|
// from the root predicate, as a proxy for "we care about the root"
|
||||||
@ -434,20 +434,20 @@ fn report_selection_error(
|
|||||||
// `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`
|
// `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`
|
||||||
self.can_eq(
|
self.can_eq(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
trait_predicate.self_ty().skip_binder(),
|
leaf_trait_predicate.self_ty().skip_binder(),
|
||||||
root_pred.self_ty().peel_refs(),
|
root_pred.self_ty().peel_refs(),
|
||||||
)
|
)
|
||||||
// `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`
|
// `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`
|
||||||
|| self.can_eq(
|
|| self.can_eq(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
trait_predicate.self_ty().skip_binder(),
|
leaf_trait_predicate.self_ty().skip_binder(),
|
||||||
root_pred.self_ty(),
|
root_pred.self_ty(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// The leaf trait and the root trait are different, so as to avoid
|
// The leaf trait and the root trait are different, so as to avoid
|
||||||
// talking about `&mut T: Trait` and instead remain talking about
|
// talking about `&mut T: Trait` and instead remain talking about
|
||||||
// `T: Trait` instead
|
// `T: Trait` instead
|
||||||
&& trait_predicate.def_id() != root_pred.def_id()
|
&& leaf_trait_predicate.def_id() != root_pred.def_id()
|
||||||
// The root trait is not `Unsize`, as to avoid talking about it in
|
// The root trait is not `Unsize`, as to avoid talking about it in
|
||||||
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
|
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
|
||||||
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
|
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
|
||||||
@ -459,13 +459,14 @@ fn report_selection_error(
|
|||||||
root_obligation,
|
root_obligation,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(trait_predicate, &obligation)
|
(leaf_trait_predicate, &obligation)
|
||||||
};
|
};
|
||||||
let trait_ref = main_trait_predicate.to_poly_trait_ref();
|
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
|
||||||
|
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
|
||||||
|
|
||||||
if let Some(guar) = self.emit_specialized_closure_kind_error(
|
if let Some(guar) = self.emit_specialized_closure_kind_error(
|
||||||
&obligation,
|
&obligation,
|
||||||
trait_ref,
|
leaf_trait_ref,
|
||||||
) {
|
) {
|
||||||
return guar;
|
return guar;
|
||||||
}
|
}
|
||||||
@ -473,7 +474,7 @@ fn report_selection_error(
|
|||||||
// FIXME(effects)
|
// FIXME(effects)
|
||||||
let predicate_is_const = false;
|
let predicate_is_const = false;
|
||||||
|
|
||||||
if let Err(guar) = trait_predicate.error_reported()
|
if let Err(guar) = leaf_trait_predicate.error_reported()
|
||||||
{
|
{
|
||||||
return guar;
|
return guar;
|
||||||
}
|
}
|
||||||
@ -507,16 +508,17 @@ fn report_selection_error(
|
|||||||
notes,
|
notes,
|
||||||
parent_label,
|
parent_label,
|
||||||
append_const_msg,
|
append_const_msg,
|
||||||
} = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file);
|
} = self.on_unimplemented_note(main_trait_ref, o, &mut long_ty_file);
|
||||||
|
|
||||||
let have_alt_message = message.is_some() || label.is_some();
|
let have_alt_message = message.is_some() || label.is_some();
|
||||||
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
|
let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id());
|
||||||
let is_unsize =
|
let is_unsize =
|
||||||
Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
|
Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
|
||||||
let (message, notes, append_const_msg) = if is_try_conversion {
|
let (message, notes, append_const_msg) = if is_try_conversion {
|
||||||
(
|
(
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"`?` couldn't convert the error to `{}`",
|
"`?` couldn't convert the error to `{}`",
|
||||||
trait_ref.skip_binder().self_ty(),
|
main_trait_ref.skip_binder().self_ty(),
|
||||||
)),
|
)),
|
||||||
vec![
|
vec![
|
||||||
"the question mark operation (`?`) implicitly performs a \
|
"the question mark operation (`?`) implicitly performs a \
|
||||||
@ -530,20 +532,20 @@ fn report_selection_error(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let err_msg = self.get_standard_error_message(
|
let err_msg = self.get_standard_error_message(
|
||||||
&main_trait_predicate,
|
main_trait_predicate,
|
||||||
message,
|
message,
|
||||||
predicate_is_const,
|
predicate_is_const,
|
||||||
append_const_msg,
|
append_const_msg,
|
||||||
post_message,
|
post_message,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (err_msg, safe_transmute_explanation) = if Some(trait_ref.def_id())
|
let (err_msg, safe_transmute_explanation) = if Some(main_trait_ref.def_id())
|
||||||
== self.tcx.lang_items().transmute_trait()
|
== self.tcx.lang_items().transmute_trait()
|
||||||
{
|
{
|
||||||
// Recompute the safe transmute reason and use that for the error reporting
|
// Recompute the safe transmute reason and use that for the error reporting
|
||||||
match self.get_safe_transmute_error_and_reason(
|
match self.get_safe_transmute_error_and_reason(
|
||||||
obligation.clone(),
|
obligation.clone(),
|
||||||
trait_ref,
|
main_trait_ref,
|
||||||
span,
|
span,
|
||||||
) {
|
) {
|
||||||
GetSafeTransmuteErrorAndReason::Silent => {
|
GetSafeTransmuteErrorAndReason::Silent => {
|
||||||
@ -571,7 +573,7 @@ fn report_selection_error(
|
|||||||
}
|
}
|
||||||
let mut suggested = false;
|
let mut suggested = false;
|
||||||
if is_try_conversion {
|
if is_try_conversion {
|
||||||
suggested = self.try_conversion_context(&obligation, trait_ref.skip_binder(), &mut err);
|
suggested = self.try_conversion_context(&obligation, main_trait_ref.skip_binder(), &mut err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) {
|
if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) {
|
||||||
@ -579,19 +581,19 @@ fn report_selection_error(
|
|||||||
ret_span,
|
ret_span,
|
||||||
format!(
|
format!(
|
||||||
"expected `{}` because of this",
|
"expected `{}` because of this",
|
||||||
trait_ref.skip_binder().self_ty()
|
main_trait_ref.skip_binder().self_ty()
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
|
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
|
||||||
self.add_tuple_trait_message(
|
self.add_tuple_trait_message(
|
||||||
obligation.cause.code().peel_derives(),
|
obligation.cause.code().peel_derives(),
|
||||||
&mut err,
|
&mut err,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait()
|
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().drop_trait()
|
||||||
&& predicate_is_const
|
&& predicate_is_const
|
||||||
{
|
{
|
||||||
err.note("`~const Drop` was renamed to `~const Destruct`");
|
err.note("`~const Drop` was renamed to `~const Destruct`");
|
||||||
@ -601,24 +603,25 @@ fn report_selection_error(
|
|||||||
let explanation = get_explanation_based_on_obligation(
|
let explanation = get_explanation_based_on_obligation(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&obligation,
|
&obligation,
|
||||||
trait_ref,
|
leaf_trait_predicate,
|
||||||
&trait_predicate,
|
|
||||||
pre_message,
|
pre_message,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.check_for_binding_assigned_block_without_tail_expression(
|
self.check_for_binding_assigned_block_without_tail_expression(
|
||||||
&obligation,
|
&obligation,
|
||||||
&mut err,
|
&mut err,
|
||||||
trait_predicate,
|
leaf_trait_predicate,
|
||||||
);
|
);
|
||||||
self.suggest_add_result_as_return_type(&obligation,
|
self.suggest_add_result_as_return_type(
|
||||||
|
&obligation,
|
||||||
&mut err,
|
&mut err,
|
||||||
trait_ref);
|
leaf_trait_predicate,
|
||||||
|
);
|
||||||
|
|
||||||
if self.suggest_add_reference_to_arg(
|
if self.suggest_add_reference_to_arg(
|
||||||
&obligation,
|
&obligation,
|
||||||
&mut err,
|
&mut err,
|
||||||
trait_predicate,
|
leaf_trait_predicate,
|
||||||
have_alt_message,
|
have_alt_message,
|
||||||
) {
|
) {
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
@ -630,7 +633,7 @@ fn report_selection_error(
|
|||||||
// If it has a custom `#[rustc_on_unimplemented]`
|
// If it has a custom `#[rustc_on_unimplemented]`
|
||||||
// error message, let's display it as the label!
|
// error message, let's display it as the label!
|
||||||
err.span_label(span, s);
|
err.span_label(span, s);
|
||||||
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
|
if !matches!(leaf_trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
|
||||||
// When the self type is a type param We don't need to "the trait
|
// When the self type is a type param We don't need to "the trait
|
||||||
// `std::marker::Sized` is not implemented for `T`" as we will point
|
// `std::marker::Sized` is not implemented for `T`" as we will point
|
||||||
// at the type param with a label to suggest constraining it.
|
// at the type param with a label to suggest constraining it.
|
||||||
@ -645,7 +648,7 @@ fn report_selection_error(
|
|||||||
if let ObligationCauseCode::Coercion { source, target } =
|
if let ObligationCauseCode::Coercion { source, target } =
|
||||||
*obligation.cause.code().peel_derives()
|
*obligation.cause.code().peel_derives()
|
||||||
{
|
{
|
||||||
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
|
if Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
|
||||||
self.suggest_borrowing_for_object_cast(
|
self.suggest_borrowing_for_object_cast(
|
||||||
&mut err,
|
&mut err,
|
||||||
root_obligation,
|
root_obligation,
|
||||||
@ -657,7 +660,7 @@ fn report_selection_error(
|
|||||||
|
|
||||||
let UnsatisfiedConst(unsatisfied_const) = self
|
let UnsatisfiedConst(unsatisfied_const) = self
|
||||||
.maybe_add_note_for_unsatisfied_const(
|
.maybe_add_note_for_unsatisfied_const(
|
||||||
&trait_predicate,
|
leaf_trait_predicate,
|
||||||
&mut err,
|
&mut err,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
@ -674,15 +677,15 @@ fn report_selection_error(
|
|||||||
err.span_label(tcx.def_span(body), s);
|
err.span_label(tcx.def_span(body), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
|
self.suggest_floating_point_literal(&obligation, &mut err, leaf_trait_ref);
|
||||||
self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate);
|
self.suggest_dereferencing_index(&obligation, &mut err, leaf_trait_predicate);
|
||||||
suggested |= self.suggest_dereferences(&obligation, &mut err, trait_predicate);
|
suggested |= self.suggest_dereferences(&obligation, &mut err, leaf_trait_predicate);
|
||||||
suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate);
|
suggested |= self.suggest_fn_call(&obligation, &mut err, leaf_trait_predicate);
|
||||||
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
|
let impl_candidates = self.find_similar_impl_candidates(leaf_trait_predicate);
|
||||||
suggested = if let &[cand] = &impl_candidates[..] {
|
suggested = if let &[cand] = &impl_candidates[..] {
|
||||||
let cand = cand.trait_ref;
|
let cand = cand.trait_ref;
|
||||||
if let (ty::FnPtr(_), ty::FnDef(..)) =
|
if let (ty::FnPtr(_), ty::FnDef(..)) =
|
||||||
(cand.self_ty().kind(), trait_ref.self_ty().skip_binder().kind())
|
(cand.self_ty().kind(), main_trait_ref.self_ty().skip_binder().kind())
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span.shrink_to_hi(),
|
span.shrink_to_hi(),
|
||||||
@ -702,31 +705,31 @@ fn report_selection_error(
|
|||||||
false
|
false
|
||||||
} || suggested;
|
} || suggested;
|
||||||
suggested |=
|
suggested |=
|
||||||
self.suggest_remove_reference(&obligation, &mut err, trait_predicate);
|
self.suggest_remove_reference(&obligation, &mut err, leaf_trait_predicate);
|
||||||
suggested |= self.suggest_semicolon_removal(
|
suggested |= self.suggest_semicolon_removal(
|
||||||
&obligation,
|
&obligation,
|
||||||
&mut err,
|
&mut err,
|
||||||
span,
|
span,
|
||||||
trait_predicate,
|
leaf_trait_predicate,
|
||||||
);
|
);
|
||||||
self.note_version_mismatch(&mut err, &trait_ref);
|
self.note_version_mismatch(&mut err, leaf_trait_ref);
|
||||||
self.suggest_remove_await(&obligation, &mut err);
|
self.suggest_remove_await(&obligation, &mut err);
|
||||||
self.suggest_derive(&obligation, &mut err, trait_predicate);
|
self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);
|
||||||
|
|
||||||
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
|
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().try_trait() {
|
||||||
self.suggest_await_before_try(
|
self.suggest_await_before_try(
|
||||||
&mut err,
|
&mut err,
|
||||||
&obligation,
|
&obligation,
|
||||||
trait_predicate,
|
leaf_trait_predicate,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.suggest_add_clone_to_arg(&obligation, &mut err, trait_predicate) {
|
if self.suggest_add_clone_to_arg(&obligation, &mut err, leaf_trait_predicate) {
|
||||||
return err.emit();
|
return err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.suggest_impl_trait(&mut err, &obligation, trait_predicate) {
|
if self.suggest_impl_trait(&mut err, &obligation, leaf_trait_predicate) {
|
||||||
return err.emit();
|
return err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,9 +744,9 @@ fn report_selection_error(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id());
|
let is_fn_trait = tcx.is_fn_trait(leaf_trait_ref.def_id());
|
||||||
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
|
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
|
||||||
*trait_ref.skip_binder().self_ty().kind()
|
*leaf_trait_ref.skip_binder().self_ty().kind()
|
||||||
{
|
{
|
||||||
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
|
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
|
||||||
} else {
|
} else {
|
||||||
@ -757,8 +760,7 @@ fn report_selection_error(
|
|||||||
|
|
||||||
self.try_to_add_help_message(
|
self.try_to_add_help_message(
|
||||||
&obligation,
|
&obligation,
|
||||||
trait_ref,
|
leaf_trait_predicate,
|
||||||
&trait_predicate,
|
|
||||||
&mut err,
|
&mut err,
|
||||||
span,
|
span,
|
||||||
is_fn_trait,
|
is_fn_trait,
|
||||||
@ -769,17 +771,17 @@ fn report_selection_error(
|
|||||||
// Changing mutability doesn't make a difference to whether we have
|
// Changing mutability doesn't make a difference to whether we have
|
||||||
// an `Unsize` impl (Fixes ICE in #71036)
|
// an `Unsize` impl (Fixes ICE in #71036)
|
||||||
if !is_unsize {
|
if !is_unsize {
|
||||||
self.suggest_change_mut(&obligation, &mut err, trait_predicate);
|
self.suggest_change_mut(&obligation, &mut err, leaf_trait_predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this error is due to `!: Trait` not implemented but `(): Trait` is
|
// If this error is due to `!: Trait` not implemented but `(): Trait` is
|
||||||
// implemented, and fallback has occurred, then it could be due to a
|
// implemented, and fallback has occurred, then it could be due to a
|
||||||
// variable that used to fallback to `()` now falling back to `!`. Issue a
|
// variable that used to fallback to `()` now falling back to `!`. Issue a
|
||||||
// note informing about the change in behaviour.
|
// note informing about the change in behaviour.
|
||||||
if trait_predicate.skip_binder().self_ty().is_never()
|
if leaf_trait_predicate.skip_binder().self_ty().is_never()
|
||||||
&& self.fallback_has_occurred
|
&& self.fallback_has_occurred
|
||||||
{
|
{
|
||||||
let predicate = trait_predicate.map_bound(|trait_pred| {
|
let predicate = leaf_trait_predicate.map_bound(|trait_pred| {
|
||||||
trait_pred.with_self_ty(self.tcx, tcx.types.unit)
|
trait_pred.with_self_ty(self.tcx, tcx.types.unit)
|
||||||
});
|
});
|
||||||
let unit_obligation = obligation.with(tcx, predicate);
|
let unit_obligation = obligation.with(tcx, predicate);
|
||||||
@ -794,8 +796,8 @@ fn report_selection_error(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.explain_hrtb_projection(&mut err, trait_predicate, obligation.param_env, &obligation.cause);
|
self.explain_hrtb_projection(&mut err, leaf_trait_predicate, obligation.param_env, &obligation.cause);
|
||||||
self.suggest_desugaring_async_fn_in_trait(&mut err, trait_ref);
|
self.suggest_desugaring_async_fn_in_trait(&mut err, main_trait_ref);
|
||||||
|
|
||||||
// Return early if the trait is Debug or Display and the invocation
|
// Return early if the trait is Debug or Display and the invocation
|
||||||
// originates within a standard library macro, because the output
|
// originates within a standard library macro, because the output
|
||||||
@ -813,15 +815,13 @@ fn report_selection_error(
|
|||||||
|
|
||||||
if in_std_macro
|
if in_std_macro
|
||||||
&& matches!(
|
&& matches!(
|
||||||
self.tcx.get_diagnostic_name(trait_ref.def_id()),
|
self.tcx.get_diagnostic_name(leaf_trait_ref.def_id()),
|
||||||
Some(sym::Debug | sym::Display)
|
Some(sym::Debug | sym::Display)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return err.emit();
|
return err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2236,11 +2236,7 @@ fn get_parent_trait_ref(
|
|||||||
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
|
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
|
||||||
/// with the same path as `trait_ref`, a help message about
|
/// with the same path as `trait_ref`, a help message about
|
||||||
/// a probable version mismatch is added to `err`
|
/// a probable version mismatch is added to `err`
|
||||||
fn note_version_mismatch(
|
fn note_version_mismatch(&self, err: &mut Diag<'_>, trait_ref: ty::PolyTraitRef<'tcx>) -> bool {
|
||||||
&self,
|
|
||||||
err: &mut Diag<'_>,
|
|
||||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
|
||||||
) -> bool {
|
|
||||||
let get_trait_impls = |trait_def_id| {
|
let get_trait_impls = |trait_def_id| {
|
||||||
let mut trait_impls = vec![];
|
let mut trait_impls = vec![];
|
||||||
self.tcx.for_each_relevant_impl(
|
self.tcx.for_each_relevant_impl(
|
||||||
@ -3060,7 +3056,7 @@ fn is_recursive_obligation(
|
|||||||
|
|
||||||
fn get_standard_error_message(
|
fn get_standard_error_message(
|
||||||
&self,
|
&self,
|
||||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
trait_predicate: ty::PolyTraitPredicate<'tcx>,
|
||||||
message: Option<String>,
|
message: Option<String>,
|
||||||
predicate_is_const: bool,
|
predicate_is_const: bool,
|
||||||
append_const_msg: Option<AppendConstMessage>,
|
append_const_msg: Option<AppendConstMessage>,
|
||||||
@ -3231,8 +3227,7 @@ fn add_tuple_trait_message(
|
|||||||
fn try_to_add_help_message(
|
fn try_to_add_help_message(
|
||||||
&self,
|
&self,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_predicate: ty::PolyTraitPredicate<'tcx>,
|
||||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
is_fn_trait: bool,
|
is_fn_trait: bool,
|
||||||
@ -3249,16 +3244,22 @@ fn try_to_add_help_message(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Try to report a help message
|
// Try to report a help message
|
||||||
|
let trait_def_id = trait_predicate.def_id();
|
||||||
if is_fn_trait
|
if is_fn_trait
|
||||||
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
|
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
trait_ref.self_ty(),
|
trait_predicate.self_ty(),
|
||||||
trait_predicate.skip_binder().polarity,
|
trait_predicate.skip_binder().polarity,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
self.add_help_message_for_fn_trait(trait_ref, err, implemented_kind, params);
|
self.add_help_message_for_fn_trait(
|
||||||
} else if !trait_ref.has_non_region_infer()
|
trait_predicate.to_poly_trait_ref(),
|
||||||
&& self.predicate_can_apply(obligation.param_env, *trait_predicate)
|
err,
|
||||||
|
implemented_kind,
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
} else if !trait_predicate.has_non_region_infer()
|
||||||
|
&& self.predicate_can_apply(obligation.param_env, trait_predicate)
|
||||||
{
|
{
|
||||||
// If a where-clause may be useful, remind the
|
// If a where-clause may be useful, remind the
|
||||||
// user that they can add it.
|
// user that they can add it.
|
||||||
@ -3269,25 +3270,25 @@ fn try_to_add_help_message(
|
|||||||
// which is somewhat confusing.
|
// which is somewhat confusing.
|
||||||
self.suggest_restricting_param_bound(
|
self.suggest_restricting_param_bound(
|
||||||
err,
|
err,
|
||||||
*trait_predicate,
|
trait_predicate,
|
||||||
None,
|
None,
|
||||||
obligation.cause.body_id,
|
obligation.cause.body_id,
|
||||||
);
|
);
|
||||||
} else if trait_ref.def_id().is_local()
|
} else if trait_def_id.is_local()
|
||||||
&& self.tcx.trait_impls_of(trait_ref.def_id()).is_empty()
|
&& self.tcx.trait_impls_of(trait_def_id).is_empty()
|
||||||
&& !self.tcx.trait_is_auto(trait_ref.def_id())
|
&& !self.tcx.trait_is_auto(trait_def_id)
|
||||||
&& !self.tcx.trait_is_alias(trait_ref.def_id())
|
&& !self.tcx.trait_is_alias(trait_def_id)
|
||||||
{
|
{
|
||||||
err.span_help(
|
err.span_help(
|
||||||
self.tcx.def_span(trait_ref.def_id()),
|
self.tcx.def_span(trait_def_id),
|
||||||
crate::fluent_generated::trait_selection_trait_has_no_impls,
|
crate::fluent_generated::trait_selection_trait_has_no_impls,
|
||||||
);
|
);
|
||||||
} else if !suggested && !unsatisfied_const {
|
} else if !suggested && !unsatisfied_const {
|
||||||
// Can't show anything else useful, try to find similar impls.
|
// Can't show anything else useful, try to find similar impls.
|
||||||
let impl_candidates = self.find_similar_impl_candidates(*trait_predicate);
|
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
|
||||||
if !self.report_similar_impl_candidates(
|
if !self.report_similar_impl_candidates(
|
||||||
&impl_candidates,
|
&impl_candidates,
|
||||||
trait_ref,
|
trait_predicate.to_poly_trait_ref(),
|
||||||
body_def_id,
|
body_def_id,
|
||||||
err,
|
err,
|
||||||
true,
|
true,
|
||||||
@ -3295,7 +3296,7 @@ fn try_to_add_help_message(
|
|||||||
) {
|
) {
|
||||||
self.report_similar_impl_candidates_for_root_obligation(
|
self.report_similar_impl_candidates_for_root_obligation(
|
||||||
obligation,
|
obligation,
|
||||||
*trait_predicate,
|
trait_predicate,
|
||||||
body_def_id,
|
body_def_id,
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
@ -3304,7 +3305,7 @@ fn try_to_add_help_message(
|
|||||||
self.suggest_convert_to_slice(
|
self.suggest_convert_to_slice(
|
||||||
err,
|
err,
|
||||||
obligation,
|
obligation,
|
||||||
trait_ref,
|
trait_predicate.to_poly_trait_ref(),
|
||||||
impl_candidates.as_slice(),
|
impl_candidates.as_slice(),
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
@ -3369,7 +3370,7 @@ fn add_help_message_for_fn_trait(
|
|||||||
|
|
||||||
fn maybe_add_note_for_unsatisfied_const(
|
fn maybe_add_note_for_unsatisfied_const(
|
||||||
&self,
|
&self,
|
||||||
_trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
_trait_predicate: ty::PolyTraitPredicate<'tcx>,
|
||||||
_err: &mut Diag<'_>,
|
_err: &mut Diag<'_>,
|
||||||
_span: Span,
|
_span: Span,
|
||||||
) -> UnsatisfiedConst {
|
) -> UnsatisfiedConst {
|
||||||
|
@ -194,7 +194,7 @@ fn predicates_reference_self(
|
|||||||
predicates
|
predicates
|
||||||
.predicates
|
.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, &trait_ref), sp))
|
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, trait_ref), sp))
|
||||||
.filter_map(|predicate| predicate_references_self(tcx, predicate))
|
.filter_map(|predicate| predicate_references_self(tcx, predicate))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +1866,7 @@ fn candidate_should_be_dropped_in_favor_of(
|
|||||||
// the param_env so that it can be given the lowest priority. See
|
// the param_env so that it can be given the lowest priority. See
|
||||||
// #50825 for the motivation for this.
|
// #50825 for the motivation for this.
|
||||||
let is_global =
|
let is_global =
|
||||||
|cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars();
|
|cand: ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars();
|
||||||
|
|
||||||
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
|
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
|
||||||
// `DiscriminantKindCandidate`, `ConstDestructCandidate`
|
// `DiscriminantKindCandidate`, `ConstDestructCandidate`
|
||||||
@ -1909,7 +1909,7 @@ fn candidate_should_be_dropped_in_favor_of(
|
|||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
ParamCandidate(ref other_cand),
|
ParamCandidate(other_cand),
|
||||||
ImplCandidate(..)
|
ImplCandidate(..)
|
||||||
| AutoImplCandidate
|
| AutoImplCandidate
|
||||||
| ClosureCandidate { .. }
|
| ClosureCandidate { .. }
|
||||||
@ -1934,12 +1934,12 @@ fn candidate_should_be_dropped_in_favor_of(
|
|||||||
//
|
//
|
||||||
// Global bounds from the where clause should be ignored
|
// Global bounds from the where clause should be ignored
|
||||||
// here (see issue #50825).
|
// here (see issue #50825).
|
||||||
DropVictim::drop_if(!is_global(other_cand))
|
DropVictim::drop_if(!is_global(*other_cand))
|
||||||
}
|
}
|
||||||
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref victim_cand)) => {
|
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(victim_cand)) => {
|
||||||
// Prefer these to a global where-clause bound
|
// Prefer these to a global where-clause bound
|
||||||
// (see issue #50825).
|
// (see issue #50825).
|
||||||
if is_global(victim_cand) { DropVictim::Yes } else { DropVictim::No }
|
if is_global(*victim_cand) { DropVictim::Yes } else { DropVictim::No }
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
ImplCandidate(_)
|
ImplCandidate(_)
|
||||||
@ -1957,12 +1957,12 @@ fn candidate_should_be_dropped_in_favor_of(
|
|||||||
| TraitUpcastingUnsizeCandidate(_)
|
| TraitUpcastingUnsizeCandidate(_)
|
||||||
| BuiltinCandidate { has_nested: true }
|
| BuiltinCandidate { has_nested: true }
|
||||||
| TraitAliasCandidate,
|
| TraitAliasCandidate,
|
||||||
ParamCandidate(ref victim_cand),
|
ParamCandidate(victim_cand),
|
||||||
) => {
|
) => {
|
||||||
// Prefer these to a global where-clause bound
|
// Prefer these to a global where-clause bound
|
||||||
// (see issue #50825).
|
// (see issue #50825).
|
||||||
DropVictim::drop_if(
|
DropVictim::drop_if(
|
||||||
is_global(victim_cand) && other.evaluation.must_apply_modulo_regions(),
|
is_global(*victim_cand) && other.evaluation.must_apply_modulo_regions(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
|
|||||||
debug!(?predicates);
|
debug!(?predicates);
|
||||||
|
|
||||||
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
||||||
pred.instantiate_supertrait(tcx, &trait_ref)
|
pred.instantiate_supertrait(tcx, trait_ref)
|
||||||
.as_trait_clause()
|
.as_trait_clause()
|
||||||
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
||||||
});
|
});
|
||||||
|
@ -125,7 +125,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
|
|||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |(pred, _)| {
|
.filter_map(move |(pred, _)| {
|
||||||
pred.instantiate_supertrait(tcx, &inner_most_trait_ref).as_trait_clause()
|
pred.instantiate_supertrait(tcx, inner_most_trait_ref).as_trait_clause()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find an unvisited supertrait
|
// Find an unvisited supertrait
|
||||||
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `&'static u32: Defaulted` is not satisfied
|
|||||||
--> $DIR/typeck-default-trait-impl-precedence.rs:19:20
|
--> $DIR/typeck-default-trait-impl-precedence.rs:19:20
|
||||||
|
|
|
|
||||||
LL | is_defaulted::<&'static u32>();
|
LL | is_defaulted::<&'static u32>();
|
||||||
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted`
|
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`, which is required by `&'static u32: Defaulted`
|
||||||
|
|
|
|
||||||
note: required for `&'static u32` to implement `Defaulted`
|
note: required for `&'static u32` to implement `Defaulted`
|
||||||
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
|
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
|
||||||
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `i32: Baz<Self>` is not satisfied
|
|||||||
--> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30
|
--> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30
|
||||||
|
|
|
|
||||||
LL | type Bar<T>: Baz<Self> = i32;
|
LL | type Bar<T>: Baz<Self> = i32;
|
||||||
| ^^^ the trait `Eq<i32>` is not implemented for `i32`, which is required by `i32: Baz<Self>`
|
| ^^^ the trait `Eq<i32>` is not implemented for `<Self as Foo>::Bar<()>`, which is required by `i32: Baz<Self>`
|
||||||
|
|
|
|
||||||
note: required for `i32` to implement `Baz<Self>`
|
note: required for `i32` to implement `Baz<Self>`
|
||||||
--> $DIR/assume-gat-normalization-for-nested-goals.rs:16:23
|
--> $DIR/assume-gat-normalization-for-nested-goals.rs:16:23
|
||||||
|
@ -46,7 +46,7 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie
|
|||||||
--> $DIR/nested_impl_trait.rs:6:46
|
--> $DIR/nested_impl_trait.rs:6:46
|
||||||
|
|
|
|
||||||
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`, which is required by `impl Into<u32>: Into<impl Debug>`
|
||||||
|
|
|
|
||||||
= help: the trait `Into<U>` is implemented for `T`
|
= help: the trait `Into<U>` is implemented for `T`
|
||||||
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
||||||
@ -55,7 +55,7 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie
|
|||||||
--> $DIR/nested_impl_trait.rs:19:34
|
--> $DIR/nested_impl_trait.rs:19:34
|
||||||
|
|
|
|
||||||
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`, which is required by `impl Into<u32>: Into<impl Debug>`
|
||||||
|
|
|
|
||||||
= help: the trait `Into<U>` is implemented for `T`
|
= help: the trait `Into<U>` is implemented for `T`
|
||||||
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
||||||
|
@ -4,7 +4,7 @@ error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads sa
|
|||||||
LL | assert_send::<&'static (dyn Dummy + 'static)>();
|
LL | assert_send::<&'static (dyn Dummy + 'static)>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
||||||
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
|
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
|
||||||
note: required by a bound in `assert_send`
|
note: required by a bound in `assert_send`
|
||||||
--> $DIR/kindck-send-object.rs:5:18
|
--> $DIR/kindck-send-object.rs:5:18
|
||||||
|
@ -4,7 +4,7 @@ error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
|
|||||||
LL | assert_send::<&'a dyn Dummy>();
|
LL | assert_send::<&'a dyn Dummy>();
|
||||||
| ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
|
| ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `&'a (dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send`
|
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send`
|
||||||
= note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
|
= note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
|
||||||
note: required by a bound in `assert_send`
|
note: required by a bound in `assert_send`
|
||||||
--> $DIR/kindck-send-object1.rs:5:18
|
--> $DIR/kindck-send-object1.rs:5:18
|
||||||
|
@ -4,7 +4,7 @@ error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads sa
|
|||||||
LL | assert_send::<&'static dyn Dummy>();
|
LL | assert_send::<&'static dyn Dummy>();
|
||||||
| ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
| ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
||||||
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
|
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
|
||||||
note: required by a bound in `assert_send`
|
note: required by a bound in `assert_send`
|
||||||
--> $DIR/kindck-send-object2.rs:3:18
|
--> $DIR/kindck-send-object2.rs:3:18
|
||||||
|
@ -4,7 +4,7 @@ error[E0277]: `&mut &mut &mut &mut Vec<i32>` is not an iterator
|
|||||||
LL | for _ in &mut &mut v {}
|
LL | for _ in &mut &mut v {}
|
||||||
| ^^^^^^^^^^^ `&mut &mut &mut &mut Vec<i32>` is not an iterator
|
| ^^^^^^^^^^^ `&mut &mut &mut &mut Vec<i32>` is not an iterator
|
||||||
|
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `&mut &mut &mut &mut Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator`
|
= help: the trait `Iterator` is not implemented for `Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator`
|
||||||
= note: required for `&mut Vec<i32>` to implement `Iterator`
|
= note: required for `&mut Vec<i32>` to implement `Iterator`
|
||||||
= note: 3 redundant requirements hidden
|
= note: 3 redundant requirements hidden
|
||||||
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
|
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
|
||||||
@ -21,7 +21,7 @@ error[E0277]: `&mut &mut &mut [u8; 1]` is not an iterator
|
|||||||
LL | for _ in &mut v {}
|
LL | for _ in &mut v {}
|
||||||
| ^^^^^^ `&mut &mut &mut [u8; 1]` is not an iterator
|
| ^^^^^^ `&mut &mut &mut [u8; 1]` is not an iterator
|
||||||
|
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `&mut &mut &mut [u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator`
|
= help: the trait `Iterator` is not implemented for `[u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator`
|
||||||
= note: required for `&mut [u8; 1]` to implement `Iterator`
|
= note: required for `&mut [u8; 1]` to implement `Iterator`
|
||||||
= note: 2 redundant requirements hidden
|
= note: 2 redundant requirements hidden
|
||||||
= note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
|
= note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
|
||||||
|
@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
|
|||||||
LL | is_send(foo());
|
LL | is_send(foo());
|
||||||
| ^^^^^ future returned by `foo` is not `Send`
|
| ^^^^^ future returned by `foo` is not `Send`
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `impl Future<Output = ()>`, which is required by `impl Future<Output = ()>: Send`
|
= help: the trait `Sync` is not implemented for `NotSync`, which is required by `impl Future<Output = ()>: Send`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/auto-with-drop_tracking_mir.rs:16:11
|
--> $DIR/auto-with-drop_tracking_mir.rs:16:11
|
||||||
|
|
|
|
||||||
|
@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): Foo` is not satisfied
|
|||||||
LL | needs_foo::<()>();
|
LL | needs_foo::<()>();
|
||||||
| ^^ the trait `Bar` is not implemented for `()`, which is required by `(): Foo`
|
| ^^ the trait `Bar` is not implemented for `()`, which is required by `(): Foo`
|
||||||
|
|
|
|
||||||
|
help: this trait has no implementations, consider adding one
|
||||||
|
--> $DIR/point-at-failing-nested.rs:4:1
|
||||||
|
|
|
||||||
|
LL | trait Bar {}
|
||||||
|
| ^^^^^^^^^
|
||||||
note: required for `()` to implement `Foo`
|
note: required for `()` to implement `Foo`
|
||||||
--> $DIR/point-at-failing-nested.rs:9:12
|
--> $DIR/point-at-failing-nested.rs:9:12
|
||||||
|
|
|
|
||||||
|
@ -6,6 +6,11 @@ LL | needs_foo(());
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
|
help: this trait has no implementations, consider adding one
|
||||||
|
--> $DIR/where-clause-doesnt-apply.rs:2:1
|
||||||
|
|
|
||||||
|
LL | trait Bar {}
|
||||||
|
| ^^^^^^^^^
|
||||||
note: required for `()` to implement `Foo`
|
note: required for `()` to implement `Foo`
|
||||||
--> $DIR/where-clause-doesnt-apply.rs:4:9
|
--> $DIR/where-clause-doesnt-apply.rs:4:9
|
||||||
|
|
|
|
||||||
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
|
|||||||
--> $DIR/root-obligation.rs:6:38
|
--> $DIR/root-obligation.rs:6:38
|
||||||
|
|
|
|
||||||
LL | .filter(|c| "aeiou".contains(c))
|
LL | .filter(|c| "aeiou".contains(c))
|
||||||
| -------- ^ the trait `Fn(char)` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
|
| -------- ^ the trait `Fn(char)` is not implemented for `char`, which is required by `&char: Pattern<'_>`
|
||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
|
@ -2,7 +2,7 @@ error[E0277]: `&u8` cannot be safely transmuted into `&UnsafeCell<u8>`
|
|||||||
--> $DIR/unsafecell.rs:27:50
|
--> $DIR/unsafecell.rs:27:50
|
||||||
|
|
|
|
||||||
LL | assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>();
|
LL | assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell<u8>`
|
||||||
|
|
|
|
||||||
note: required by a bound in `is_maybe_transmutable`
|
note: required by a bound in `is_maybe_transmutable`
|
||||||
--> $DIR/unsafecell.rs:12:14
|
--> $DIR/unsafecell.rs:12:14
|
||||||
@ -17,7 +17,7 @@ error[E0277]: `&UnsafeCell<u8>` cannot be safely transmuted into `&UnsafeCell<u8
|
|||||||
--> $DIR/unsafecell.rs:29:62
|
--> $DIR/unsafecell.rs:29:62
|
||||||
|
|
|
|
||||||
LL | assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>();
|
LL | assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell<u8>`
|
||||||
|
|
|
|
||||||
note: required by a bound in `is_maybe_transmutable`
|
note: required by a bound in `is_maybe_transmutable`
|
||||||
--> $DIR/unsafecell.rs:12:14
|
--> $DIR/unsafecell.rs:12:14
|
||||||
|
16
tests/ui/typeck/suggest-similar-impls-for-root-obligation.rs
Normal file
16
tests/ui/typeck/suggest-similar-impls-for-root-obligation.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
trait Foo<'s> {}
|
||||||
|
|
||||||
|
impl<'s> Foo<'s> for () {}
|
||||||
|
|
||||||
|
struct Bar;
|
||||||
|
|
||||||
|
impl<'s, T: Foo<'s>> From<T> for Bar {
|
||||||
|
fn from(_: T) -> Self {
|
||||||
|
Bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: Bar = ((),).into();
|
||||||
|
//~^ ERROR he trait bound `((),): Into<Bar>` is not satisfied
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
error[E0277]: the trait bound `((),): Into<Bar>` is not satisfied
|
||||||
|
--> $DIR/suggest-similar-impls-for-root-obligation.rs:14:24
|
||||||
|
|
|
||||||
|
LL | let _: Bar = ((),).into();
|
||||||
|
| ^^^^ the trait `Foo<'_>` is not implemented for `((),)`, which is required by `((),): Into<_>`
|
||||||
|
|
|
||||||
|
= help: the trait `Foo<'_>` is implemented for `()`
|
||||||
|
= help: for that trait implementation, expected `()`, found `((),)`
|
||||||
|
note: required for `Bar` to implement `From<((),)>`
|
||||||
|
--> $DIR/suggest-similar-impls-for-root-obligation.rs:7:22
|
||||||
|
|
|
||||||
|
LL | impl<'s, T: Foo<'s>> From<T> for Bar {
|
||||||
|
| ------- ^^^^^^^ ^^^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
= note: required for `((),)` to implement `Into<Bar>`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user