1
Fork 0

Auto merge of #135095 - matthiaskrgr:rollup-tmgxckq, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #133964 (core: implement `bool::select_unpredictable`)
 - #135001 (Allow using self-contained LLD in bootstrap)
 - #135055 (Report impl method has stricter requirements even when RPITIT inference gets in the way)
 - #135064 (const-in-pattern: test that the PartialEq impl does not need to be const)
 - #135066 (bootstrap: support `./x check run-make-support`)
 - #135069 (remove unused function params)
 - #135084 (Update carrying_mul_add test to tolerate `nuw`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-01-04 10:02:59 +00:00
commit f17cf744f5
25 changed files with 270 additions and 86 deletions

View file

@ -529,6 +529,26 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
// Check that the where clauses of the impl are satisfied by the hybrid param env.
// You might ask -- what does this have to do with RPITIT inference? Nothing.
// We check these because if the where clauses of the signatures do not match
// up, then we don't want to give spurious other errors that point at the RPITITs.
// They're not necessary to check, though, because we already check them in
// `compare_method_predicate_entailment`.
let impl_m_own_bounds = tcx.predicates_of(impl_m_def_id).instantiate_own_identity();
for (predicate, span) in impl_m_own_bounds {
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
let cause =
ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
impl_item_def_id: impl_m_def_id,
trait_item_def_id: trait_m.def_id,
kind: impl_m.kind,
});
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
}
// Normalize the impl signature with fresh variables for lifetime inference.
let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
let impl_sig = ocx.normalize(

View file

@ -69,10 +69,10 @@ impl<'tcx> Ty<'tcx> {
/// description in error messages. This is used in the primary span label. Beyond what
/// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
/// ADTs with no type arguments.
pub fn is_simple_text(self, tcx: TyCtxt<'tcx>) -> bool {
pub fn is_simple_text(self) -> bool {
match self.kind() {
Adt(_, args) => args.non_erasable_generics().next().is_none(),
Ref(_, ty, _) => ty.is_simple_text(tcx),
Ref(_, ty, _) => ty.is_simple_text(),
_ => self.is_simple_ty(),
}
}

View file

@ -491,6 +491,10 @@ fn type_has_partial_eq_impl<'tcx>(
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
// can ensure that the type really implements `PartialEq`.
// We also do *not* require `const PartialEq`, not even in `const fn`. This violates the model
// that patterns can only do things that the code could also do without patterns, but it is
// needed for backwards compatibility. The actual pattern matching compares primitive values,
// `PartialEq::eq` never gets invoked, so there's no risk of us running non-const code.
(
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
automatically_derived,

View file

@ -1822,9 +1822,6 @@ impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> {
fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &CoroutineLayout<'tcx>, body: &Body<'tcx>) {
let mut linted_tys = FxHashSet::default();
// We want a user-facing param-env.
let param_env = tcx.param_env(body.source.def_id());
for (variant, yield_source_info) in
layout.variant_fields.iter().zip(&layout.variant_source_info)
{
@ -1838,7 +1835,7 @@ fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &CoroutineLayout<'tcx>, bo
continue;
};
check_must_not_suspend_ty(tcx, decl.ty, hir_id, param_env, SuspendCheckData {
check_must_not_suspend_ty(tcx, decl.ty, hir_id, SuspendCheckData {
source_span: decl.source_info.span,
yield_span: yield_source_info.span,
plural_len: 1,
@ -1868,7 +1865,6 @@ fn check_must_not_suspend_ty<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
hir_id: hir::HirId,
param_env: ty::ParamEnv<'tcx>,
data: SuspendCheckData<'_>,
) -> bool {
if ty.is_unit() {
@ -1883,16 +1879,13 @@ fn check_must_not_suspend_ty<'tcx>(
ty::Adt(_, args) if ty.is_box() => {
let boxed_ty = args.type_at(0);
let allocator_ty = args.type_at(1);
check_must_not_suspend_ty(tcx, boxed_ty, hir_id, param_env, SuspendCheckData {
check_must_not_suspend_ty(tcx, boxed_ty, hir_id, SuspendCheckData {
descr_pre: &format!("{}boxed ", data.descr_pre),
..data
}) || check_must_not_suspend_ty(
tcx,
allocator_ty,
hir_id,
param_env,
SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data },
)
}) || check_must_not_suspend_ty(tcx, allocator_ty, hir_id, SuspendCheckData {
descr_pre: &format!("{}allocator ", data.descr_pre),
..data
})
}
ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),
// FIXME: support adding the attribute to TAITs
@ -1937,7 +1930,7 @@ fn check_must_not_suspend_ty<'tcx>(
let mut has_emitted = false;
for (i, ty) in fields.iter().enumerate() {
let descr_post = &format!(" in tuple element {i}");
if check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
if check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData {
descr_post,
..data
}) {
@ -1948,7 +1941,7 @@ fn check_must_not_suspend_ty<'tcx>(
}
ty::Array(ty, len) => {
let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData {
descr_pre,
// FIXME(must_not_suspend): This is wrong. We should handle printing unevaluated consts.
plural_len: len.try_to_target_usize(tcx).unwrap_or(0) as usize + 1,
@ -1959,10 +1952,7 @@ fn check_must_not_suspend_ty<'tcx>(
// may not be considered live across the await point.
ty::Ref(_region, ty, _mutability) => {
let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
descr_pre,
..data
})
check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
}
_ => false,
}

View file

@ -1496,8 +1496,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
ValuePairs::Terms(ExpectedFound { expected, found }) => {
match (expected.unpack(), found.unpack()) {
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
let is_simple_err = expected.is_simple_text(self.tcx)
&& found.is_simple_text(self.tcx);
let is_simple_err =
expected.is_simple_text() && found.is_simple_text();
OpaqueTypesVisitor::visit_expected_found(
self.tcx, expected, found, span,
)
@ -1736,8 +1736,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
if !(values.expected.is_simple_text(self.tcx)
&& values.found.is_simple_text(self.tcx))
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|| (exp_found.is_some_and(|ef| {
// This happens when the type error is a subset of the expectation,
// like when you have two references but one is `usize` and the other