From d4ee408afc59b36ff59b6fd12d47c1beeba8e985 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 25 Sep 2024 19:19:22 -0400 Subject: [PATCH 1/3] Check allow instantiating object trait binder when upcasting and in new solver --- .../src/solve/trait_goals.rs | 6 ++--- .../src/traits/select/mod.rs | 6 ++--- tests/ui/coercion/sub-principals.rs | 27 +++++++++++++++++++ .../higher-ranked-upcasting-ok.current.stderr | 22 --------------- .../higher-ranked-upcasting-ok.next.stderr | 14 ---------- .../higher-ranked-upcasting-ok.rs | 12 +++++---- .../higher-ranked-upcasting-ub.current.stderr | 8 +++--- tests/ui/traits/trait-upcasting/sub.rs | 26 ++++++++++++++++++ 8 files changed, 70 insertions(+), 51 deletions(-) create mode 100644 tests/ui/coercion/sub-principals.rs delete mode 100644 tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr delete mode 100644 tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr create mode 100644 tests/ui/traits/trait-upcasting/sub.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 781ca127e15..0befe7f5e8a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -896,7 +896,7 @@ where && ecx .probe(|_| ProbeKind::UpcastProjectionCompatibility) .enter(|ecx| -> Result<(), NoSolution> { - ecx.eq(param_env, source_projection, target_projection)?; + ecx.sub(param_env, source_projection, target_projection)?; let _ = ecx.try_evaluate_added_goals()?; Ok(()) }) @@ -909,7 +909,7 @@ where // Check that a's supertrait (upcast_principal) is compatible // with the target (b_ty). ty::ExistentialPredicate::Trait(target_principal) => { - ecx.eq( + ecx.sub( param_env, upcast_principal.unwrap(), bound.rebind(target_principal), @@ -934,7 +934,7 @@ where Certainty::AMBIGUOUS, ); } - ecx.eq(param_env, source_projection, target_projection)?; + ecx.sub(param_env, source_projection, target_projection)?; } // Check that b_ty's auto traits are present in a_ty's bounds. ty::ExistentialPredicate::AutoTrait(def_id) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cbc17a058f6..2922a4898e9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2582,12 +2582,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .eq( + .sup( DefineOpaqueTypes::Yes, + bound.rebind(target_principal), upcast_principal.map_bound(|trait_ref| { ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) }), - bound.rebind(target_principal), ) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), @@ -2620,7 +2620,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, source_projection, target_projection) + .sup(DefineOpaqueTypes::Yes, target_projection, source_projection) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), ); diff --git a/tests/ui/coercion/sub-principals.rs b/tests/ui/coercion/sub-principals.rs new file mode 100644 index 00000000000..c38769f0d09 --- /dev/null +++ b/tests/ui/coercion/sub-principals.rs @@ -0,0 +1,27 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Verify that the unsize goal can cast a higher-ranked trait goal to +// a non-higer-ranked instantiation. + +#![feature(unsize)] + +use std::marker::Unsize; + +fn test() +where + T: Unsize, +{ +} + +fn main() { + test:: Fn(&'a ()) -> &'a (), dyn Fn(&'static ()) -> &'static ()>(); + + trait Foo<'a, 'b> {} + test:: Foo<'a, 'b>, dyn for<'a> Foo<'a, 'a>>(); + + trait Bar<'a> {} + test:: Bar<'a>, dyn Bar<'_>>(); +} diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr deleted file mode 100644 index 098ab71e946..00000000000 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/higher-ranked-upcasting-ok.rs:17:5 - | -LL | x - | ^ one type is more general than the other - | - = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` - found existential trait ref `for<'a> Supertrait<'a, 'a>` - -error[E0308]: mismatched types - --> $DIR/higher-ranked-upcasting-ok.rs:17:5 - | -LL | x - | ^ one type is more general than the other - | - = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` - found existential trait ref `for<'a> Supertrait<'a, 'a>` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr deleted file mode 100644 index ac516fd6975..00000000000 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/higher-ranked-upcasting-ok.rs:17:5 - | -LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> { - | ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type -LL | x - | ^ expected trait `Supertrait`, found trait `Subtrait` - | - = note: expected reference `&dyn for<'a> Supertrait<'a, 'a>` - found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs index 00743203179..7f793e1269f 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs @@ -1,19 +1,21 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ check-pass // We should be able to instantiate a binder during trait upcasting. // This test could be `check-pass`, but we should make sure that we // do so in both trait solvers. -#![feature(trait_upcasting)] -#![crate_type = "rlib"] -trait Supertrait<'a, 'b> {} +#![feature(trait_upcasting)] + +trait Supertrait<'a, 'b> {} trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} impl<'a> Supertrait<'a, 'a> for () {} impl<'a> Subtrait<'a, 'a> for () {} fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> { - x //~ ERROR mismatched types - //[current]~^ ERROR mismatched types + x } + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr index bac82983268..e5885ea35a7 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | x | ^ one type is more general than the other | - = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>` - found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + found existential trait ref `for<'a> Supertrait<'a, 'a>` error[E0308]: mismatched types --> $DIR/higher-ranked-upcasting-ub.rs:22:5 @@ -13,8 +13,8 @@ error[E0308]: mismatched types LL | x | ^ one type is more general than the other | - = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>` - found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + found existential trait ref `for<'a> Supertrait<'a, 'a>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/trait-upcasting/sub.rs b/tests/ui/traits/trait-upcasting/sub.rs new file mode 100644 index 00000000000..255c4895b7f --- /dev/null +++ b/tests/ui/traits/trait-upcasting/sub.rs @@ -0,0 +1,26 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Verify that the unsize goal can cast a higher-ranked trait goal to +// a non-higer-ranked instantiation. + +#![feature(unsize)] + +use std::marker::Unsize; + +fn test() +where + T: Unsize, +{ +} + +fn main() { + test:: Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>(); + + trait Foo: for<'a> Bar<'a> {} + trait Bar<'a> {} + test::>(); + test::>(); +} From 4fb097a5de14399b86dda519e1e597104a15b3b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Sep 2024 23:20:59 -0400 Subject: [PATCH 2/3] Instantiate binders when checking supertrait upcasting --- compiler/rustc_infer/src/infer/at.rs | 19 +++- .../src/solve/eval_ctxt/mod.rs | 16 ++-- .../src/solve/trait_goals.rs | 49 ++++++---- .../src/traits/select/mod.rs | 96 +++++++++++++++---- 4 files changed, 132 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 9f6a1763866..37f7f04db3f 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -159,7 +159,24 @@ impl<'a, 'tcx> At<'a, 'tcx> { ToTrace::to_trace(self.cause, true, expected, actual), self.param_env, define_opaque_types, - ); + ToTrace::to_trace(self.cause, expected, actual), + expected, + actual, + ) + } + + /// Makes `expected == actual`. + pub fn eq_trace( + self, + define_opaque_types: DefineOpaqueTypes, + trace: TypeTrace<'tcx>, + expected: T, + actual: T, + ) -> InferResult<'tcx, ()> + where + T: Relate>, + { + let mut fields = CombineFields::new(self.infcx, trace, self.param_env, define_opaque_types); fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?; Ok(InferOk { value: (), diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 12ad0724b5c..932875b759f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -448,10 +448,10 @@ where } } } else { - self.delegate.enter_forall(kind, |kind| { - let goal = goal.with(self.cx(), ty::Binder::dummy(kind)); - self.add_goal(GoalSource::InstantiateHigherRanked, goal); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + self.enter_forall(kind, |ecx, kind| { + let goal = goal.with(ecx.cx(), ty::Binder::dummy(kind)); + ecx.add_goal(GoalSource::InstantiateHigherRanked, goal); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } } @@ -840,12 +840,14 @@ where self.delegate.instantiate_binder_with_infer(value) } + /// `enter_forall`, but takes `&mut self` and passes it back through the + /// callback since it can't be aliased during the call. pub(super) fn enter_forall + Copy, U>( - &self, + &mut self, value: ty::Binder, - f: impl FnOnce(T) -> U, + f: impl FnOnce(&mut Self, T) -> U, ) -> U { - self.delegate.enter_forall(value, f) + self.delegate.enter_forall(value, |value| f(self, value)) } pub(super) fn resolve_vars_if_possible(&self, value: T) -> T diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 0befe7f5e8a..493bbf1e665 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -895,10 +895,13 @@ where source_projection.item_def_id() == target_projection.item_def_id() && ecx .probe(|_| ProbeKind::UpcastProjectionCompatibility) - .enter(|ecx| -> Result<(), NoSolution> { - ecx.sub(param_env, source_projection, target_projection)?; - let _ = ecx.try_evaluate_added_goals()?; - Ok(()) + .enter(|ecx| -> Result<_, NoSolution> { + ecx.enter_forall(target_projection, |ecx, target_projection| { + let source_projection = + ecx.instantiate_binder_with_infer(source_projection); + ecx.eq(param_env, source_projection, target_projection)?; + ecx.try_evaluate_added_goals() + }) }) .is_ok() }; @@ -909,11 +912,14 @@ where // Check that a's supertrait (upcast_principal) is compatible // with the target (b_ty). ty::ExistentialPredicate::Trait(target_principal) => { - ecx.sub( - param_env, - upcast_principal.unwrap(), - bound.rebind(target_principal), - )?; + let source_principal = upcast_principal.unwrap(); + let target_principal = bound.rebind(target_principal); + ecx.enter_forall(target_principal, |ecx, target_principal| { + let source_principal = + ecx.instantiate_binder_with_infer(source_principal); + ecx.eq(param_env, source_principal, target_principal)?; + ecx.try_evaluate_added_goals() + })?; } // Check that b_ty's projection is satisfied by exactly one of // a_ty's projections. First, we look through the list to see if @@ -934,7 +940,12 @@ where Certainty::AMBIGUOUS, ); } - ecx.sub(param_env, source_projection, target_projection)?; + ecx.enter_forall(target_projection, |ecx, target_projection| { + let source_projection = + ecx.instantiate_binder_with_infer(source_projection); + ecx.eq(param_env, source_projection, target_projection)?; + ecx.try_evaluate_added_goals() + })?; } // Check that b_ty's auto traits are present in a_ty's bounds. ty::ExistentialPredicate::AutoTrait(def_id) => { @@ -1187,17 +1198,15 @@ where ) -> Result>, NoSolution>, ) -> Result, NoSolution> { self.probe_trait_candidate(source).enter(|ecx| { - ecx.add_goals( - GoalSource::ImplWhereBound, - constituent_tys(ecx, goal.predicate.self_ty())? - .into_iter() - .map(|ty| { - ecx.enter_forall(ty, |ty| { - goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty)) - }) + let goals = constituent_tys(ecx, goal.predicate.self_ty())? + .into_iter() + .map(|ty| { + ecx.enter_forall(ty, |ecx, ty| { + goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty)) }) - .collect::>(), - ); + }) + .collect::>(); + ecx.add_goals(GoalSource::ImplWhereBound, goals); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2922a4898e9..c3042ab9636 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -16,6 +16,7 @@ use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; +use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::relate::TypeRelation; use rustc_infer::traits::TraitObligation; use rustc_middle::bug; @@ -44,7 +45,7 @@ use super::{ TraitQueryMode, const_evaluatable, project, util, wf, }; use crate::error_reporting::InferCtxtErrorExt; -use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener}; +use crate::infer::{InferCtxt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt}; @@ -2579,16 +2580,32 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // Check that a_ty's supertrait (upcast_principal) is compatible // with the target (b_ty). ty::ExistentialPredicate::Trait(target_principal) => { + let hr_source_principal = upcast_principal.map_bound(|trait_ref| { + ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) + }); + let hr_target_principal = bound.rebind(target_principal); + nested.extend( self.infcx - .at(&obligation.cause, obligation.param_env) - .sup( - DefineOpaqueTypes::Yes, - bound.rebind(target_principal), - upcast_principal.map_bound(|trait_ref| { - ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) - }), - ) + .enter_forall(hr_target_principal, |target_principal| { + let source_principal = + self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + hr_source_principal, + ); + self.infcx.at(&obligation.cause, obligation.param_env).eq_trace( + DefineOpaqueTypes::Yes, + ToTrace::to_trace( + &obligation.cause, + true, + hr_target_principal, + hr_source_principal, + ), + target_principal, + source_principal, + ) + }) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), ); @@ -2599,19 +2616,41 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // return ambiguity. Otherwise, if exactly one matches, equate // it with b_ty's projection. ty::ExistentialPredicate::Projection(target_projection) => { - let target_projection = bound.rebind(target_projection); + let hr_target_projection = bound.rebind(target_projection); + let mut matching_projections = - a_data.projection_bounds().filter(|source_projection| { + a_data.projection_bounds().filter(|&hr_source_projection| { // Eager normalization means that we can just use can_eq // here instead of equating and processing obligations. - source_projection.item_def_id() == target_projection.item_def_id() - && self.infcx.can_eq( - obligation.param_env, - *source_projection, - target_projection, - ) + hr_source_projection.item_def_id() == hr_target_projection.item_def_id() + && self.infcx.probe(|_| { + self.infcx + .enter_forall(hr_target_projection, |target_projection| { + let source_projection = + self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + hr_source_projection, + ); + self.infcx + .at(&obligation.cause, obligation.param_env) + .eq_trace( + DefineOpaqueTypes::Yes, + ToTrace::to_trace( + &obligation.cause, + true, + hr_target_projection, + hr_source_projection, + ), + target_projection, + source_projection, + ) + }) + .is_ok() + }) }); - let Some(source_projection) = matching_projections.next() else { + + let Some(hr_source_projection) = matching_projections.next() else { return Err(SelectionError::Unimplemented); }; if matching_projections.next().is_some() { @@ -2619,8 +2658,25 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } nested.extend( self.infcx - .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::Yes, target_projection, source_projection) + .enter_forall(hr_target_projection, |target_projection| { + let source_projection = + self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + hr_source_projection, + ); + self.infcx.at(&obligation.cause, obligation.param_env).eq_trace( + DefineOpaqueTypes::Yes, + ToTrace::to_trace( + &obligation.cause, + true, + hr_target_projection, + hr_source_projection, + ), + target_projection, + source_projection, + ) + }) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), ); From d753aba3b342a286fbaa198b43154cf7fbe68692 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Sep 2024 23:22:48 -0400 Subject: [PATCH 3/3] Get rid of a_is_expected from ToTrace --- compiler/rustc_infer/src/infer/at.rs | 145 +++++------------- .../src/traits/select/mod.rs | 3 - 2 files changed, 36 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 37f7f04db3f..6ce47db8b9b 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -92,12 +92,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub trait ToTrace<'tcx>: Relate> + Copy { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx>; + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>; } impl<'a, 'tcx> At<'a, 'tcx> { @@ -116,7 +111,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { { let mut fields = CombineFields::new( self.infcx, - ToTrace::to_trace(self.cause, true, expected, actual), + ToTrace::to_trace(self.cause, expected, actual), self.param_env, define_opaque_types, ); @@ -136,7 +131,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { { let mut fields = CombineFields::new( self.infcx, - ToTrace::to_trace(self.cause, true, expected, actual), + ToTrace::to_trace(self.cause, expected, actual), self.param_env, define_opaque_types, ); @@ -154,10 +149,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { where T: ToTrace<'tcx>, { - let mut fields = CombineFields::new( - self.infcx, - ToTrace::to_trace(self.cause, true, expected, actual), - self.param_env, + self.eq_trace( define_opaque_types, ToTrace::to_trace(self.cause, expected, actual), expected, @@ -209,7 +201,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { assert!(self.infcx.next_trait_solver()); let mut fields = CombineFields::new( self.infcx, - ToTrace::to_trace(self.cause, true, expected, actual), + ToTrace::to_trace(self.cause, expected, actual), self.param_env, DefineOpaqueTypes::Yes, ); @@ -301,7 +293,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { { let mut fields = CombineFields::new( self.infcx, - ToTrace::to_trace(self.cause, true, expected, actual), + ToTrace::to_trace(self.cause, expected, actual), self.param_env, define_opaque_types, ); @@ -323,7 +315,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { { let mut fields = CombineFields::new( self.infcx, - ToTrace::to_trace(self.cause, true, expected, actual), + ToTrace::to_trace(self.cause, expected, actual), self.param_env, define_opaque_types, ); @@ -333,18 +325,13 @@ impl<'a, 'tcx> At<'a, 'tcx> { } impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { match (a, b) { (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => { - ToTrace::to_trace(cause, a_is_expected, trait_ref_a, trait_ref_b) + ToTrace::to_trace(cause, trait_ref_a, trait_ref_b) } (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => { - ToTrace::to_trace(cause, a_is_expected, ty_a, ty_b) + ToTrace::to_trace(cause, ty_a, ty_b) } (ImplSubject::Trait(_), ImplSubject::Inherent(_)) | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => { @@ -355,65 +342,45 @@ impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> { } impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), + values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())), } } } impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::Regions(ExpectedFound::new(true, a, b)), } } } impl<'tcx> ToTrace<'tcx> for Const<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())), + values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())), } } } impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), values: match (a.unpack(), b.unpack()) { (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => { - ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b)) + ValuePairs::Regions(ExpectedFound::new(true, a, b)) } (GenericArgKind::Type(a), GenericArgKind::Type(b)) => { - ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())) + ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())) } (GenericArgKind::Const(a), GenericArgKind::Const(b)) => { - ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())) + ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())) } ( @@ -436,72 +403,47 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { } impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::Terms(ExpectedFound::new(true, a, b)), } } } impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::TraitRefs(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::TraitRefs(ExpectedFound::new(true, a, b)), } } } impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a.into(), b.into())), + values: ValuePairs::Aliases(ExpectedFound::new(true, a.into(), b.into())), } } } impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::Aliases(ExpectedFound::new(true, a, b)), } } } impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), values: ValuePairs::PolySigs(ExpectedFound::new( - a_is_expected, + true, ty::Binder::dummy(a), ty::Binder::dummy(b), )), @@ -510,43 +452,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { } impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::PolySigs(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::PolySigs(ExpectedFound::new(true, a, b)), } } } impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(true, a, b)), } } } impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> { - fn to_trace( - cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self, - ) -> TypeTrace<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: ValuePairs::ExistentialProjection(ExpectedFound::new(a_is_expected, a, b)), + values: ValuePairs::ExistentialProjection(ExpectedFound::new(true, a, b)), } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c3042ab9636..dbe05a33328 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2598,7 +2598,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { DefineOpaqueTypes::Yes, ToTrace::to_trace( &obligation.cause, - true, hr_target_principal, hr_source_principal, ), @@ -2638,7 +2637,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { DefineOpaqueTypes::Yes, ToTrace::to_trace( &obligation.cause, - true, hr_target_projection, hr_source_projection, ), @@ -2669,7 +2667,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { DefineOpaqueTypes::Yes, ToTrace::to_trace( &obligation.cause, - true, hr_target_projection, hr_source_projection, ),