Skip to content

Commit 63e2986

Browse files
Don't use leaf trait ref if passing in non-root trait predicate
1 parent 4dc24ae commit 63e2986

File tree

4 files changed

+63
-31
lines changed

4 files changed

+63
-31
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
412412
let bound_predicate = obligation.predicate.kind();
413413
match bound_predicate.skip_binder() {
414414
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
415-
let trait_predicate = bound_predicate.rebind(trait_predicate);
416-
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
415+
let trait_predicate =
416+
self.resolve_vars_if_possible(bound_predicate.rebind(trait_predicate));
417417

418418
// Let's use the root obligation as the main message, when we care about the
419419
// most general case ("X doesn't implement Pattern<'_>") over the case that
@@ -461,11 +461,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
461461
} else {
462462
(trait_predicate, &obligation)
463463
};
464-
let trait_ref = main_trait_predicate.to_poly_trait_ref();
464+
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
465465

466466
if let Some(guar) = self.emit_specialized_closure_kind_error(
467467
&obligation,
468-
trait_ref,
468+
main_trait_ref,
469469
) {
470470
return guar;
471471
}
@@ -507,16 +507,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
507507
notes,
508508
parent_label,
509509
append_const_msg,
510-
} = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file);
510+
} = self.on_unimplemented_note(main_trait_ref, o, &mut long_ty_file);
511511
let have_alt_message = message.is_some() || label.is_some();
512-
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
512+
let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id());
513513
let is_unsize =
514-
Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
514+
Some(main_trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
515515
let (message, notes, append_const_msg) = if is_try_conversion {
516516
(
517517
Some(format!(
518518
"`?` couldn't convert the error to `{}`",
519-
trait_ref.skip_binder().self_ty(),
519+
main_trait_ref.skip_binder().self_ty(),
520520
)),
521521
vec![
522522
"the question mark operation (`?`) implicitly performs a \
@@ -537,13 +537,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
537537
post_message,
538538
);
539539

540-
let (err_msg, safe_transmute_explanation) = if Some(trait_ref.def_id())
540+
let (err_msg, safe_transmute_explanation) = if Some(main_trait_ref.def_id())
541541
== self.tcx.lang_items().transmute_trait()
542542
{
543543
// Recompute the safe transmute reason and use that for the error reporting
544544
match self.get_safe_transmute_error_and_reason(
545545
obligation.clone(),
546-
trait_ref,
546+
main_trait_ref,
547547
span,
548548
) {
549549
GetSafeTransmuteErrorAndReason::Silent => {
@@ -571,27 +571,27 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
571571
}
572572
let mut suggested = false;
573573
if is_try_conversion {
574-
suggested = self.try_conversion_context(&obligation, trait_ref.skip_binder(), &mut err);
574+
suggested = self.try_conversion_context(&obligation, main_trait_ref.skip_binder(), &mut err);
575575
}
576576

577577
if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) {
578578
err.span_label(
579579
ret_span,
580580
format!(
581581
"expected `{}` because of this",
582-
trait_ref.skip_binder().self_ty()
582+
main_trait_ref.skip_binder().self_ty()
583583
),
584584
);
585585
}
586586

587-
if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
587+
if Some(main_trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
588588
self.add_tuple_trait_message(
589589
obligation.cause.code().peel_derives(),
590590
&mut err,
591591
);
592592
}
593593

594-
if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait()
594+
if Some(main_trait_ref.def_id()) == tcx.lang_items().drop_trait()
595595
&& predicate_is_const
596596
{
597597
err.note("`~const Drop` was renamed to `~const Destruct`");
@@ -601,8 +601,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
601601
let explanation = get_explanation_based_on_obligation(
602602
self.tcx,
603603
&obligation,
604-
trait_ref,
605-
&trait_predicate,
604+
main_trait_ref,
605+
&main_trait_predicate,
606606
pre_message,
607607
);
608608

@@ -626,7 +626,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
626626
// If it has a custom `#[rustc_on_unimplemented]`
627627
// error message, let's display it as the label!
628628
err.span_label(span, s);
629-
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
629+
if !matches!(main_trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
630630
// When the self type is a type param We don't need to "the trait
631631
// `std::marker::Sized` is not implemented for `T`" as we will point
632632
// at the type param with a label to suggest constraining it.
@@ -641,7 +641,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
641641
if let ObligationCauseCode::Coercion { source, target } =
642642
*obligation.cause.code().peel_derives()
643643
{
644-
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
644+
if Some(main_trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
645645
self.suggest_borrowing_for_object_cast(
646646
&mut err,
647647
root_obligation,
@@ -670,15 +670,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
670670
err.span_label(tcx.def_span(body), s);
671671
}
672672

673-
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
673+
self.suggest_floating_point_literal(&obligation, &mut err, &main_trait_ref);
674674
self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate);
675675
suggested |= self.suggest_dereferences(&obligation, &mut err, trait_predicate);
676676
suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate);
677677
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
678678
suggested = if let &[cand] = &impl_candidates[..] {
679679
let cand = cand.trait_ref;
680680
if let (ty::FnPtr(_), ty::FnDef(..)) =
681-
(cand.self_ty().kind(), trait_ref.self_ty().skip_binder().kind())
681+
(cand.self_ty().kind(), main_trait_ref.self_ty().skip_binder().kind())
682682
{
683683
err.span_suggestion(
684684
span.shrink_to_hi(),
@@ -705,11 +705,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
705705
span,
706706
trait_predicate,
707707
);
708-
self.note_version_mismatch(&mut err, &trait_ref);
708+
self.note_version_mismatch(&mut err, &main_trait_ref);
709709
self.suggest_remove_await(&obligation, &mut err);
710710
self.suggest_derive(&obligation, &mut err, trait_predicate);
711711

712-
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
712+
if Some(main_trait_ref.def_id()) == tcx.lang_items().try_trait() {
713713
self.suggest_await_before_try(
714714
&mut err,
715715
&obligation,
@@ -737,9 +737,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
737737
);
738738
}
739739

740-
let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id());
740+
let is_fn_trait = tcx.is_fn_trait(main_trait_ref.def_id());
741741
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
742-
*trait_ref.skip_binder().self_ty().kind()
742+
*main_trait_ref.skip_binder().self_ty().kind()
743743
{
744744
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
745745
} else {
@@ -753,8 +753,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
753753

754754
self.try_to_add_help_message(
755755
&obligation,
756-
trait_ref,
757-
&trait_predicate,
756+
main_trait_ref,
757+
&main_trait_predicate,
758758
&mut err,
759759
span,
760760
is_fn_trait,
@@ -791,7 +791,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
791791
}
792792

793793
self.explain_hrtb_projection(&mut err, trait_predicate, obligation.param_env, &obligation.cause);
794-
self.suggest_desugaring_async_fn_in_trait(&mut err, trait_ref);
794+
self.suggest_desugaring_async_fn_in_trait(&mut err, main_trait_ref);
795795

796796
// Return early if the trait is Debug or Display and the invocation
797797
// originates within a standard library macro, because the output
@@ -809,15 +809,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
809809

810810
if in_std_macro
811811
&& matches!(
812-
self.tcx.get_diagnostic_name(trait_ref.def_id()),
812+
self.tcx.get_diagnostic_name(main_trait_ref.def_id()),
813813
Some(sym::Debug | sym::Display)
814814
)
815815
{
816816
return err.emit();
817817
}
818818

819-
820-
821819
err
822820
}
823821

tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `&'static u32: Defaulted` is not satisfied
22
--> $DIR/typeck-default-trait-impl-precedence.rs:19:20
33
|
44
LL | is_defaulted::<&'static u32>();
5-
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted`
5+
| ^^^^^^^^^^^^ the trait `Defaulted` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted`
66
|
77
note: required for `&'static u32` to implement `Defaulted`
88
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
trait Foo<'s> {}
2+
3+
impl<'s> Foo<'s> for () {}
4+
5+
struct Bar;
6+
7+
impl<'s, T: Foo<'s>> From<T> for Bar {
8+
fn from(_: T) -> Self {
9+
Bar
10+
}
11+
}
12+
13+
fn main() {
14+
let _: Bar = ((),).into();
15+
//~^ ERROR he trait bound `((),): Into<Bar>` is not satisfied
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0277]: the trait bound `((),): Into<Bar>` is not satisfied
2+
--> $DIR/suggest-similar-impls-for-root-obligation.rs:14:24
3+
|
4+
LL | let _: Bar = ((),).into();
5+
| ^^^^ the trait `Into<Bar>` is not implemented for `((),)`, which is required by `((),): Into<_>`
6+
|
7+
note: required for `Bar` to implement `From<((),)>`
8+
--> $DIR/suggest-similar-impls-for-root-obligation.rs:7:22
9+
|
10+
LL | impl<'s, T: Foo<'s>> From<T> for Bar {
11+
| ------- ^^^^^^^ ^^^
12+
| |
13+
| unsatisfied trait bound introduced here
14+
= note: required for `((),)` to implement `Into<Bar>`
15+
16+
error: aborting due to 1 previous error
17+
18+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)