Skip to content

Commit c5dc558

Browse files
committed
Auto merge of #147169 - jhpratt:rollup-65ooei8, r=jhpratt
Rollup of 4 pull requests Successful merges: - #145883 (Make macOS dist build configuration match where reasonable) - #146457 (Skip cleanups on unsupported targets) - #147152 (builtin `Fn`-trait impls: instantiate binder before the return type `Sized` check) - #147153 ([rustdoc] Move doc cfg propagation pass before items stripping passes) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 29b7717 + 745b8f6 commit c5dc558

File tree

16 files changed

+249
-167
lines changed

16 files changed

+249
-167
lines changed

compiler/rustc_mir_transform/src/abort_unwinding_calls.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustc_ast::InlineAsmOptions;
33
use rustc_middle::mir::*;
44
use rustc_middle::span_bug;
55
use rustc_middle::ty::{self, TyCtxt, layout};
6+
use rustc_span::sym;
67
use rustc_target::spec::PanicStrategy;
78

89
/// A pass that runs which is targeted at ensuring that codegen guarantees about
@@ -33,6 +34,19 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
3334
return;
3435
}
3536

37+
// Represent whether this compilation target fundamentally doesn't
38+
// support unwinding at all at an ABI level. If this the target has no
39+
// support for unwinding then cleanup actions, for example, are all
40+
// unnecessary and can be considered unreachable.
41+
//
42+
// Currently this is only true for wasm targets on panic=abort when the
43+
// `exception-handling` target feature is disabled. In such a
44+
// configuration it's illegal to emit exception-related instructions so
45+
// it's not possible to unwind.
46+
let target_supports_unwinding = !(tcx.sess.target.is_like_wasm
47+
&& tcx.sess.panic_strategy() == PanicStrategy::Abort
48+
&& !tcx.asm_target_features(def_id).contains(&sym::exception_handling));
49+
3650
// Here we test for this function itself whether its ABI allows
3751
// unwinding or not.
3852
let body_ty = tcx.type_of(def_id).skip_binder();
@@ -54,12 +68,18 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
5468
let Some(terminator) = &mut block.terminator else { continue };
5569
let span = terminator.source_info.span;
5670

57-
// If we see an `UnwindResume` terminator inside a function that cannot unwind, we need
58-
// to replace it with `UnwindTerminate`.
59-
if let TerminatorKind::UnwindResume = &terminator.kind
60-
&& !body_can_unwind
61-
{
62-
terminator.kind = TerminatorKind::UnwindTerminate(UnwindTerminateReason::Abi);
71+
// If we see an `UnwindResume` terminator inside a function then:
72+
//
73+
// * If the target doesn't support unwinding at all, then this is an
74+
// unreachable block.
75+
// * If the body cannot unwind, we need to replace it with
76+
// `UnwindTerminate`.
77+
if let TerminatorKind::UnwindResume = &terminator.kind {
78+
if !target_supports_unwinding {
79+
terminator.kind = TerminatorKind::Unreachable;
80+
} else if !body_can_unwind {
81+
terminator.kind = TerminatorKind::UnwindTerminate(UnwindTerminateReason::Abi);
82+
}
6383
}
6484

6585
if block.is_cleanup {
@@ -93,8 +113,9 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
93113
_ => continue,
94114
};
95115

96-
if !call_can_unwind {
97-
// If this function call can't unwind, then there's no need for it
116+
if !call_can_unwind || !target_supports_unwinding {
117+
// If this function call can't unwind, or if the target doesn't
118+
// support unwinding at all, then there's no need for it
98119
// to have a landing pad. This means that we can remove any cleanup
99120
// registered for it (and turn it into `UnwindAction::Unreachable`).
100121
let cleanup = block.terminator_mut().unwind_mut().unwrap();

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/eval_ctxt/mod.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -633,28 +633,19 @@ where
633633
// the certainty of all the goals.
634634
#[instrument(level = "trace", skip(self))]
635635
pub(super) fn try_evaluate_added_goals(&mut self) -> Result<Certainty, NoSolution> {
636-
let mut response = Ok(Certainty::overflow(false));
637636
for _ in 0..FIXPOINT_STEP_LIMIT {
638-
// FIXME: This match is a bit ugly, it might be nice to change the inspect
639-
// stuff to use a closure instead. which should hopefully simplify this a bit.
640637
match self.evaluate_added_goals_step() {
641-
Ok(Some(cert)) => {
642-
response = Ok(cert);
643-
break;
644-
}
645638
Ok(None) => {}
639+
Ok(Some(cert)) => return Ok(cert),
646640
Err(NoSolution) => {
647-
response = Err(NoSolution);
648-
break;
641+
self.tainted = Err(NoSolution);
642+
return Err(NoSolution);
649643
}
650644
}
651645
}
652646

653-
if response.is_err() {
654-
self.tainted = Err(NoSolution);
655-
}
656-
657-
response
647+
debug!("try_evaluate_added_goals: encountered overflow");
648+
Ok(Certainty::overflow(false))
658649
}
659650

660651
/// Iterate over all added goals: returning `Ok(Some(_))` in case we can stop rerunning.

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),

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,7 @@ symbols! {
940940
ermsb_target_feature,
941941
exact_div,
942942
except,
943+
exception_handling: "exception-handling",
943944
exchange_malloc,
944945
exclusive_range_pattern,
945946
exhaustive_integer_patterns,

0 commit comments

Comments
 (0)