Auto merge of #121394 - oli-obk:define_opaque_types, r=compiler-errors
some smaller DefiningOpaqueTypes::No -> Yes switches r? `@compiler-errors` These are some easy cases, so let's get them out of the way first. I added tests exercising the specialization code paths that I believe weren't tested so far. follow-up to https://github.com/rust-lang/rust/pull/117348
This commit is contained in:
commit
a4b11c8e60
31 changed files with 522 additions and 49 deletions
|
@ -720,7 +720,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
) -> Result<(), NoSolution> {
|
||||
self.infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(DefineOpaqueTypes::No, lhs, rhs)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.eq(DefineOpaqueTypes::Yes, lhs, rhs)
|
||||
.map(|InferOk { value: (), obligations }| {
|
||||
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
|
||||
})
|
||||
|
@ -759,7 +760,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
) -> Result<(), NoSolution> {
|
||||
self.infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.sub(DefineOpaqueTypes::No, sub, sup)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.sub(DefineOpaqueTypes::Yes, sub, sup)
|
||||
.map(|InferOk { value: (), obligations }| {
|
||||
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
|
||||
})
|
||||
|
@ -779,7 +781,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
) -> Result<(), NoSolution> {
|
||||
self.infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.relate(DefineOpaqueTypes::No, lhs, variance, rhs)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.relate(DefineOpaqueTypes::Yes, lhs, variance, rhs)
|
||||
.map(|InferOk { value: (), obligations }| {
|
||||
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
|
||||
})
|
||||
|
@ -803,7 +806,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
|
||||
self.infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(DefineOpaqueTypes::No, lhs, rhs)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.eq(DefineOpaqueTypes::Yes, lhs, rhs)
|
||||
.map(|InferOk { value: (), obligations }| {
|
||||
obligations.into_iter().map(|o| o.into()).collect()
|
||||
})
|
||||
|
|
|
@ -182,7 +182,8 @@ fn rematch_impl<'tcx>(
|
|||
|
||||
let mut nested = infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.eq(DefineOpaqueTypes::Yes, goal.predicate.trait_ref, impl_trait_ref)
|
||||
.map_err(|_| SelectionError::Unimplemented)?
|
||||
.into_obligations();
|
||||
|
||||
|
@ -257,7 +258,8 @@ fn rematch_unsize<'tcx>(
|
|||
nested.extend(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.eq(DefineOpaqueTypes::No, a_elem_ty, b_elem_ty)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty)
|
||||
.expect("expected rematch to succeed")
|
||||
.into_obligations(),
|
||||
);
|
||||
|
@ -300,7 +302,8 @@ fn rematch_unsize<'tcx>(
|
|||
nested.extend(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
|
||||
.expect("expected rematch to succeed")
|
||||
.into_obligations(),
|
||||
);
|
||||
|
@ -329,7 +332,8 @@ fn rematch_unsize<'tcx>(
|
|||
nested.extend(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
|
||||
// New solver ignores DefineOpaqueTypes, so choose Yes for consistency
|
||||
.eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
|
||||
.expect("expected rematch to succeed")
|
||||
.into_obligations(),
|
||||
);
|
||||
|
|
|
@ -477,7 +477,8 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
if ty.is_ty_var() {
|
||||
let Ok(InferOk { value: (), obligations }) =
|
||||
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// Comparing against a type variable never registers hidden types anyway
|
||||
DefineOpaqueTypes::Yes,
|
||||
ty,
|
||||
Ty::new_placeholder(
|
||||
self.infcx.tcx,
|
||||
|
@ -504,7 +505,9 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
if ct.is_ct_infer() {
|
||||
let Ok(InferOk { value: (), obligations }) =
|
||||
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// The types of the constants are the same, so there is no hidden type
|
||||
// registration happening anyway.
|
||||
DefineOpaqueTypes::Yes,
|
||||
ct,
|
||||
ty::Const::new_placeholder(
|
||||
self.infcx.tcx,
|
||||
|
@ -532,7 +535,8 @@ fn plug_infer_with_placeholders<'tcx>(
|
|||
if r.is_var() {
|
||||
let Ok(InferOk { value: (), obligations }) =
|
||||
self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// Lifetimes don't contain opaque types (or any types for that matter).
|
||||
DefineOpaqueTypes::Yes,
|
||||
r,
|
||||
ty::Region::new_placeholder(
|
||||
self.infcx.tcx,
|
||||
|
|
|
@ -3842,7 +3842,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
self.probe(|_| {
|
||||
match self
|
||||
.at(&ObligationCause::misc(expr.span, body_id), param_env)
|
||||
.eq(DefineOpaqueTypes::No, expected, actual)
|
||||
// Doesn't actually matter if we define opaque types here, this is just used for
|
||||
// diagnostics, and the result is never kept around.
|
||||
.eq(DefineOpaqueTypes::Yes, expected, actual)
|
||||
{
|
||||
Ok(_) => (), // We ignore nested obligations here for now.
|
||||
Err(err) => type_diffs.push(err),
|
||||
|
|
|
@ -429,7 +429,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
// as the cause of an overflow.
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// Only really excercised by generic_const_exprs
|
||||
DefineOpaqueTypes::Yes,
|
||||
ct.ty(),
|
||||
ty,
|
||||
) {
|
||||
|
@ -571,7 +572,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
if let Ok(new_obligations) = infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.trace(c1, c2)
|
||||
.eq(DefineOpaqueTypes::No, a.args, b.args)
|
||||
// Can define opaque types as this is only reachable with
|
||||
// `generic_const_exprs`
|
||||
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
|
||||
{
|
||||
return ProcessResult::Changed(mk_pending(
|
||||
new_obligations.into_obligations(),
|
||||
|
@ -582,7 +585,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
(_, _) => {
|
||||
if let Ok(new_obligations) = infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(DefineOpaqueTypes::No, c1, c2)
|
||||
// Can define opaque types as this is only reachable with
|
||||
// `generic_const_exprs`
|
||||
.eq(DefineOpaqueTypes::Yes, c1, c2)
|
||||
{
|
||||
return ProcessResult::Changed(mk_pending(
|
||||
new_obligations.into_obligations(),
|
||||
|
@ -623,7 +628,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
match (evaluate(c1), evaluate(c2)) {
|
||||
(Ok(c1), Ok(c2)) => {
|
||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// Can define opaque types as this is only reachable with
|
||||
// `generic_const_exprs`
|
||||
DefineOpaqueTypes::Yes,
|
||||
c1,
|
||||
c2,
|
||||
) {
|
||||
|
|
|
@ -906,7 +906,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.trace(c1, c2)
|
||||
.eq(DefineOpaqueTypes::No, a.args, b.args)
|
||||
// Can define opaque types as this is only reachable with
|
||||
// `generic_const_exprs`
|
||||
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
|
||||
{
|
||||
return self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
|
@ -919,7 +921,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
if let Ok(InferOk { obligations, value: () }) = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(DefineOpaqueTypes::No, c1, c2)
|
||||
// Can define opaque types as this is only reachable with
|
||||
// `generic_const_exprs`
|
||||
.eq(DefineOpaqueTypes::Yes, c1, c2)
|
||||
{
|
||||
return self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
|
@ -949,7 +953,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
match (evaluate(c1), evaluate(c2)) {
|
||||
(Ok(c1), Ok(c2)) => {
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// Can define opaque types as this is only reachable with
|
||||
// `generic_const_exprs`
|
||||
DefineOpaqueTypes::Yes,
|
||||
c1,
|
||||
c2,
|
||||
) {
|
||||
|
@ -982,7 +988,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
// Only really excercised by generic_const_exprs
|
||||
DefineOpaqueTypes::Yes,
|
||||
ct.ty(),
|
||||
ty,
|
||||
) {
|
||||
|
|
|
@ -247,7 +247,12 @@ fn fulfill_implication<'tcx>(
|
|||
// do the impls unify? If not, no specialization.
|
||||
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(DefineOpaqueTypes::No, source_trait, target_trait)
|
||||
// Ok to use `Yes`, as all the generic params are already replaced by inference variables,
|
||||
// which will match the opaque type no matter if it is defining or not.
|
||||
// Any concrete type that would match the opaque would already be handled by coherence rules,
|
||||
// and thus either be ok to match here and already have errored, or it won't match, in which
|
||||
// case there is no issue anyway.
|
||||
.eq(DefineOpaqueTypes::Yes, source_trait, target_trait)
|
||||
else {
|
||||
debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait);
|
||||
return Err(());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue