Skip to content

Commit 098a568

Browse files
committed
Fn-trait goals, eagerly instantiate binder
to avoid overflow from proving `for<'a> opaque<'a>: Sized`
1 parent 7af913f commit 098a568

File tree

4 files changed

+90
-117
lines changed

4 files changed

+90
-117
lines changed

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
664664
pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
665665
cx: I,
666666
self_ty: I::Ty,
667-
) -> Result<(ty::Binder<I, (I::FnInputTys, I::Ty)>, I::FunctionId, I::GenericArgs), NoSolution> {
667+
) -> Result<(ty::Binder<I, (I::Ty, I::Ty)>, I::FunctionId, I::GenericArgs), NoSolution> {
668668
match self_ty.kind() {
669669
ty::FnDef(def_id, args) => {
670670
let sig = cx.fn_sig(def_id);
@@ -673,7 +673,8 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
673673
&& cx.fn_is_const(def_id)
674674
{
675675
Ok((
676-
sig.instantiate(cx, args).map_bound(|sig| (sig.inputs(), sig.output())),
676+
sig.instantiate(cx, args)
677+
.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
677678
def_id,
678679
args,
679680
))

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,12 @@ where
234234
let self_ty = goal.predicate.self_ty();
235235
let (inputs_and_output, def_id, args) =
236236
structural_traits::extract_fn_def_from_const_callable(cx, self_ty)?;
237+
let (inputs, output) = ecx.instantiate_binder_with_infer(inputs_and_output);
237238

238239
// A built-in `Fn` impl only holds if the output is sized.
239240
// (FIXME: technically we only need to check this if the type is a fn ptr...)
240-
let output_is_sized_pred = inputs_and_output.map_bound(|(_, output)| {
241-
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
242-
});
241+
let output_is_sized_pred =
242+
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
243243
let requirements = cx
244244
.const_conditions(def_id.into())
245245
.iter_instantiated(cx, args)
@@ -251,15 +251,12 @@ where
251251
})
252252
.chain([(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))]);
253253

254-
let pred = inputs_and_output
255-
.map_bound(|(inputs, _)| {
256-
ty::TraitRef::new(
257-
cx,
258-
goal.predicate.def_id(),
259-
[goal.predicate.self_ty(), Ty::new_tup(cx, inputs.as_slice())],
260-
)
261-
})
262-
.to_host_effect_clause(cx, goal.predicate.constness);
254+
let pred = ty::Binder::dummy(ty::TraitRef::new(
255+
cx,
256+
goal.predicate.def_id(),
257+
[goal.predicate.self_ty(), inputs],
258+
))
259+
.to_host_effect_clause(cx, goal.predicate.constness);
263260

264261
Self::probe_and_consider_implied_clause(
265262
ecx,

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 57 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -451,23 +451,22 @@ where
451451
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
452452
}
453453
};
454+
let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
454455

455456
// A built-in `Fn` impl only holds if the output is sized.
456457
// (FIXME: technically we only need to check this if the type is a fn ptr...)
457-
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
458-
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
459-
});
458+
let output_is_sized_pred =
459+
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
460460

461-
let pred = tupled_inputs_and_output
462-
.map_bound(|(inputs, output)| ty::ProjectionPredicate {
463-
projection_term: ty::AliasTerm::new(
464-
cx,
465-
goal.predicate.def_id(),
466-
[goal.predicate.self_ty(), inputs],
467-
),
468-
term: output.into(),
469-
})
470-
.upcast(cx);
461+
let pred = ty::ProjectionPredicate {
462+
projection_term: ty::AliasTerm::new(
463+
cx,
464+
goal.predicate.def_id(),
465+
[goal.predicate.self_ty(), inputs],
466+
),
467+
term: output.into(),
468+
}
469+
.upcast(cx);
471470

472471
Self::probe_and_consider_implied_clause(
473472
ecx,
@@ -497,76 +496,56 @@ where
497496
goal_kind,
498497
env_region,
499498
)?;
499+
let AsyncCallableRelevantTypes {
500+
tupled_inputs_ty,
501+
output_coroutine_ty,
502+
coroutine_return_ty,
503+
} = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
500504

501505
// A built-in `AsyncFn` impl only holds if the output is sized.
502506
// (FIXME: technically we only need to check this if the type is a fn ptr...)
503-
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
504-
|AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
505-
ty::TraitRef::new(
506-
cx,
507-
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
508-
[output_ty],
509-
)
510-
},
507+
let output_is_sized_pred = ty::TraitRef::new(
508+
cx,
509+
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
510+
[output_coroutine_ty],
511511
);
512512

513-
let pred = tupled_inputs_and_output_and_coroutine
514-
.map_bound(
515-
|AsyncCallableRelevantTypes {
516-
tupled_inputs_ty,
517-
output_coroutine_ty,
518-
coroutine_return_ty,
519-
}| {
520-
let (projection_term, term) = if cx
521-
.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallOnceFuture)
522-
{
523-
(
524-
ty::AliasTerm::new(
525-
cx,
526-
goal.predicate.def_id(),
527-
[goal.predicate.self_ty(), tupled_inputs_ty],
528-
),
529-
output_coroutine_ty.into(),
530-
)
531-
} else if cx
532-
.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallRefFuture)
533-
{
534-
(
535-
ty::AliasTerm::new(
536-
cx,
537-
goal.predicate.def_id(),
538-
[
539-
I::GenericArg::from(goal.predicate.self_ty()),
540-
tupled_inputs_ty.into(),
541-
env_region.into(),
542-
],
543-
),
544-
output_coroutine_ty.into(),
545-
)
546-
} else if cx
547-
.is_lang_item(goal.predicate.def_id(), SolverLangItem::AsyncFnOnceOutput)
548-
{
549-
(
550-
ty::AliasTerm::new(
551-
cx,
552-
goal.predicate.def_id(),
553-
[
554-
I::GenericArg::from(goal.predicate.self_ty()),
555-
tupled_inputs_ty.into(),
556-
],
557-
),
558-
coroutine_return_ty.into(),
559-
)
560-
} else {
561-
panic!(
562-
"no such associated type in `AsyncFn*`: {:?}",
563-
goal.predicate.def_id()
564-
)
565-
};
566-
ty::ProjectionPredicate { projection_term, term }
567-
},
568-
)
569-
.upcast(cx);
513+
let (projection_term, term) =
514+
if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallOnceFuture) {
515+
(
516+
ty::AliasTerm::new(
517+
cx,
518+
goal.predicate.def_id(),
519+
[goal.predicate.self_ty(), tupled_inputs_ty],
520+
),
521+
output_coroutine_ty.into(),
522+
)
523+
} else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallRefFuture) {
524+
(
525+
ty::AliasTerm::new(
526+
cx,
527+
goal.predicate.def_id(),
528+
[
529+
I::GenericArg::from(goal.predicate.self_ty()),
530+
tupled_inputs_ty.into(),
531+
env_region.into(),
532+
],
533+
),
534+
output_coroutine_ty.into(),
535+
)
536+
} else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::AsyncFnOnceOutput) {
537+
(
538+
ty::AliasTerm::new(
539+
cx,
540+
goal.predicate.def_id(),
541+
[goal.predicate.self_ty(), tupled_inputs_ty],
542+
),
543+
coroutine_return_ty.into(),
544+
)
545+
} else {
546+
panic!("no such associated type in `AsyncFn*`: {:?}", goal.predicate.def_id())
547+
};
548+
let pred = ty::ProjectionPredicate { projection_term, term }.upcast(cx);
570549

571550
Self::probe_and_consider_implied_clause(
572551
ecx,

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -369,18 +369,16 @@ where
369369
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
370370
}
371371
};
372+
let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
372373

373374
// A built-in `Fn` impl only holds if the output is sized.
374375
// (FIXME: technically we only need to check this if the type is a fn ptr...)
375-
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
376-
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
377-
});
376+
let output_is_sized_pred =
377+
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
378378

379-
let pred = tupled_inputs_and_output
380-
.map_bound(|(inputs, _)| {
381-
ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
382-
})
383-
.upcast(cx);
379+
let pred =
380+
ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
381+
.upcast(cx);
384382
Self::probe_and_consider_implied_clause(
385383
ecx,
386384
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
@@ -408,28 +406,26 @@ where
408406
// This region doesn't matter because we're throwing away the coroutine type
409407
Region::new_static(cx),
410408
)?;
409+
let AsyncCallableRelevantTypes {
410+
tupled_inputs_ty,
411+
output_coroutine_ty,
412+
coroutine_return_ty: _,
413+
} = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
411414

412415
// A built-in `AsyncFn` impl only holds if the output is sized.
413416
// (FIXME: technically we only need to check this if the type is a fn ptr...)
414-
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
415-
|AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
416-
ty::TraitRef::new(
417-
cx,
418-
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
419-
[output_coroutine_ty],
420-
)
421-
},
417+
let output_is_sized_pred = ty::TraitRef::new(
418+
cx,
419+
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
420+
[output_coroutine_ty],
422421
);
423422

424-
let pred = tupled_inputs_and_output_and_coroutine
425-
.map_bound(|AsyncCallableRelevantTypes { tupled_inputs_ty, .. }| {
426-
ty::TraitRef::new(
427-
cx,
428-
goal.predicate.def_id(),
429-
[goal.predicate.self_ty(), tupled_inputs_ty],
430-
)
431-
})
432-
.upcast(cx);
423+
let pred = ty::TraitRef::new(
424+
cx,
425+
goal.predicate.def_id(),
426+
[goal.predicate.self_ty(), tupled_inputs_ty],
427+
)
428+
.upcast(cx);
433429
Self::probe_and_consider_implied_clause(
434430
ecx,
435431
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),

0 commit comments

Comments
 (0)