Auto merge of #139845 - Zalathar:rollup-u5u5y1v, r=Zalathar

Rollup of 17 pull requests

Successful merges:

 - #138374 (Enable contracts for const functions)
 - #138380 (ci: add runners for vanilla LLVM 20)
 - #138393 (Allow const patterns of matches to contain pattern types)
 - #139517 (std: sys: process: uefi: Use NULL stdin by default)
 - #139554 (std: add Output::exit_ok)
 - #139660 (compiletest: Add an experimental new executor to replace libtest)
 - #139669 (Overhaul `AssocItem`)
 - #139671 (Proc macro span API redesign: Replace proc_macro::SourceFile by Span::{file, local_file})
 - #139750 (std/thread: Use default stack size from menuconfig for NuttX)
 - #139772 (Remove `hir::Map`)
 - #139785 (Let CStrings be either 1 or 2 byte aligned.)
 - #139789 (do not unnecessarily leak auto traits in item bounds)
 - #139791 (drop global where-bounds before merging candidates)
 - #139798 (normalize: prefer `ParamEnv` over `AliasBound` candidates)
 - #139822 (Fix: Map EOPNOTSUPP to ErrorKind::Unsupported on Unix)
 - #139833 (Fix some HIR pretty-printing problems)
 - #139836 (Basic tests of MPMC receiver cloning)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-04-15 08:02:23 +00:00
173 changed files with 2499 additions and 994 deletions

View File

@@ -443,13 +443,13 @@ fn best_definition_site_of_opaque<'tcx>(
let impl_def_id = tcx.local_parent(parent);
for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
match assoc.kind {
ty::AssocKind::Const | ty::AssocKind::Fn => {
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local())
{
return Some(span);
}
}
ty::AssocKind::Type => {}
ty::AssocKind::Type { .. } => {}
}
}
@@ -740,7 +740,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
for &assoc_item in assoc_items.in_definition_order() {
match assoc_item.kind {
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
ty::AssocKind::Type { .. } if assoc_item.defaultness(tcx).has_value() => {
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
tcx,
@@ -942,7 +942,7 @@ fn check_impl_items_against_trait<'tcx>(
if res.is_ok() {
match ty_impl_item.kind {
ty::AssocKind::Fn => {
ty::AssocKind::Fn { .. } => {
compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait(
tcx,
ty_impl_item,
@@ -952,8 +952,8 @@ fn check_impl_items_against_trait<'tcx>(
.instantiate_identity(),
);
}
ty::AssocKind::Const => {}
ty::AssocKind::Type => {}
ty::AssocKind::Const { .. } => {}
ty::AssocKind::Type { .. } => {}
}
}

View File

@@ -43,9 +43,11 @@ pub(super) fn compare_impl_item(
debug!(?impl_trait_ref);
match impl_item.kind {
ty::AssocKind::Fn => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
ty::AssocKind::Type => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref),
ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref),
ty::AssocKind::Fn { .. } => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
ty::AssocKind::Type { .. } => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref),
ty::AssocKind::Const { .. } => {
compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref)
}
}
}
@@ -651,7 +653,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
cause.span,
E0053,
"method `{}` has an incompatible return type for trait",
trait_m.name
trait_m.name()
);
infcx.err_ctxt().note_type_err(
&mut diag,
@@ -1029,11 +1031,11 @@ fn report_trait_method_mismatch<'tcx>(
impl_err_span,
E0053,
"method `{}` has an incompatible type for trait",
trait_m.name
trait_m.name()
);
match &terr {
TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
if trait_m.fn_has_self_parameter =>
if trait_m.is_method() =>
{
let ty = trait_sig.inputs()[0];
let sugg = get_self_string(ty, |ty| ty == impl_trait_ref.self_ty());
@@ -1252,7 +1254,7 @@ fn compare_self_type<'tcx>(
get_self_string(self_arg_ty, can_eq_self)
};
match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
match (trait_m.is_method(), impl_m.is_method()) {
(false, false) | (true, true) => {}
(false, true) => {
@@ -1263,14 +1265,14 @@ fn compare_self_type<'tcx>(
impl_m_span,
E0185,
"method `{}` has a `{}` declaration in the impl, but not in the trait",
trait_m.name,
trait_m.name(),
self_descr
);
err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
err.span_label(span, format!("trait method declared without `{self_descr}`"));
} else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
}
return Err(err.emit_unless(delay));
}
@@ -1283,14 +1285,14 @@ fn compare_self_type<'tcx>(
impl_m_span,
E0186,
"method `{}` has a `{}` declaration in the trait, but not in the impl",
trait_m.name,
trait_m.name(),
self_descr
);
err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
err.span_label(span, format!("`{self_descr}` used in trait"));
} else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
}
return Err(err.emit_unless(delay));
@@ -1360,7 +1362,7 @@ fn compare_number_of_generics<'tcx>(
let mut err_occurred = None;
for (kind, trait_count, impl_count) in matchings {
if impl_count != trait_count {
let arg_spans = |kind: ty::AssocKind, generics: &hir::Generics<'_>| {
let arg_spans = |item: &ty::AssocItem, generics: &hir::Generics<'_>| {
let mut spans = generics
.params
.iter()
@@ -1370,7 +1372,7 @@ fn compare_number_of_generics<'tcx>(
} => {
// A fn can have an arbitrary number of extra elided lifetimes for the
// same signature.
!matches!(kind, ty::AssocKind::Fn)
!item.is_fn()
}
_ => true,
})
@@ -1383,7 +1385,7 @@ fn compare_number_of_generics<'tcx>(
};
let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() {
let trait_item = tcx.hir_expect_trait_item(def_id);
let arg_spans: Vec<Span> = arg_spans(trait_.kind, trait_item.generics);
let arg_spans: Vec<Span> = arg_spans(&trait_, trait_item.generics);
let impl_trait_spans: Vec<Span> = trait_item
.generics
.params
@@ -1409,7 +1411,7 @@ fn compare_number_of_generics<'tcx>(
_ => None,
})
.collect();
let spans = arg_spans(impl_.kind, impl_item.generics);
let spans = arg_spans(&impl_, impl_item.generics);
let span = spans.first().copied();
let mut err = tcx.dcx().struct_span_err(
@@ -1418,7 +1420,7 @@ fn compare_number_of_generics<'tcx>(
"{} `{}` has {} {kind} parameter{} but its trait \
declaration has {} {kind} parameter{}",
item_kind,
trait_.name,
trait_.name(),
impl_count,
pluralize!(impl_count),
trait_count,
@@ -1509,7 +1511,7 @@ fn compare_number_of_method_arguments<'tcx>(
impl_span,
E0050,
"method `{}` has {} but the declaration in trait `{}` has {}",
trait_m.name,
trait_m.name(),
potentially_plural_count(impl_number_args, "parameter"),
tcx.def_path_str(trait_m.def_id),
trait_number_args
@@ -1524,7 +1526,7 @@ fn compare_number_of_method_arguments<'tcx>(
),
);
} else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
}
err.span_label(
@@ -1578,7 +1580,7 @@ fn compare_synthetic_generics<'tcx>(
impl_span,
E0643,
"method `{}` has incompatible signature for trait",
trait_m.name
trait_m.name()
);
err.span_label(trait_span, "declaration in trait here");
if impl_synthetic {
@@ -1700,7 +1702,7 @@ fn compare_generic_param_kinds<'tcx>(
trait_item: ty::AssocItem,
delay: bool,
) -> Result<(), ErrorGuaranteed> {
assert_eq!(impl_item.kind, trait_item.kind);
assert_eq!(impl_item.as_tag(), trait_item.as_tag());
let ty_const_params_of = |def_id| {
tcx.generics_of(def_id).own_params.iter().filter(|param| {
@@ -1738,7 +1740,7 @@ fn compare_generic_param_kinds<'tcx>(
E0053,
"{} `{}` has an incompatible generic parameter for trait `{}`",
impl_item.descr(),
trait_item.name,
trait_item.name(),
&tcx.def_path_str(tcx.parent(trait_item.def_id))
);
@@ -1874,7 +1876,7 @@ fn compare_const_predicate_entailment<'tcx>(
cause.span,
E0326,
"implemented const `{}` has an incompatible type for trait",
trait_ct.name
trait_ct.name()
);
let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| {
@@ -2232,16 +2234,19 @@ fn param_env_with_gat_bounds<'tcx>(
// of the RPITITs associated with the same body. This is because checking
// the item bounds of RPITITs often involves nested RPITITs having to prove
// bounds about themselves.
let impl_tys_to_install = match impl_ty.opt_rpitit_info {
None => vec![impl_ty],
Some(
ty::ImplTraitInTraitData::Impl { fn_def_id }
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
) => tcx
let impl_tys_to_install = match impl_ty.kind {
ty::AssocKind::Type {
data:
ty::AssocTypeData::Rpitit(
ty::ImplTraitInTraitData::Impl { fn_def_id }
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
),
} => tcx
.associated_types_for_impl_traits_in_associated_fn(fn_def_id)
.iter()
.map(|def_id| tcx.associated_item(*def_id))
.collect(),
_ => vec![impl_ty],
};
for impl_ty in impl_tys_to_install {

View File

@@ -217,15 +217,11 @@ pub(crate) fn check_intrinsic_type(
};
(n_tps, 0, 0, inputs, output, hir::Safety::Unsafe)
} else if intrinsic_name == sym::contract_check_ensures {
// contract_check_ensures::<'a, Ret, C>(&'a Ret, C)
// where C: impl Fn(&'a Ret) -> bool,
// contract_check_ensures::<Ret, C>(Ret, C) -> Ret
// where C: for<'a> Fn(&'a Ret) -> bool,
//
// so: two type params, one lifetime param, 0 const params, two inputs, no return
let p = generics.param_at(0, tcx);
let r = ty::Region::new_early_param(tcx, p.to_early_bound_region_data());
let ref_ret = Ty::new_imm_ref(tcx, r, param(1));
(2, 1, 0, vec![ref_ret, param(2)], tcx.types.unit, hir::Safety::Safe)
// so: two type params, 0 lifetime param, 0 const params, two inputs, no return
(2, 0, 0, vec![param(0), param(1)], param(1), hir::Safety::Safe)
} else {
let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
let (n_tps, n_cts, inputs, output) = match intrinsic_name {

View File

@@ -205,7 +205,7 @@ fn missing_items_err(
let missing_items_msg = missing_items
.clone()
.map(|trait_item| trait_item.name.to_string())
.map(|trait_item| trait_item.name().to_string())
.collect::<Vec<_>>()
.join("`, `");
@@ -236,7 +236,7 @@ fn missing_items_err(
let code = format!("{padding}{snippet}\n{padding}");
if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) {
missing_trait_item_label
.push(errors::MissingTraitItemLabel { span, item: trait_item.name });
.push(errors::MissingTraitItemLabel { span, item: trait_item.name() });
missing_trait_item.push(errors::MissingTraitItemSuggestion {
span: sugg_sp,
code,
@@ -407,14 +407,14 @@ fn fn_sig_suggestion<'tcx>(
.enumerate()
.map(|(i, ty)| {
Some(match ty.kind() {
ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
ty::Param(_) if assoc.is_method() && i == 0 => "self".to_string(),
ty::Ref(reg, ref_ty, mutability) if i == 0 => {
let reg = format!("{reg} ");
let reg = match &reg[..] {
"'_ " | " " => "",
reg => reg,
};
if assoc.fn_has_self_parameter {
if assoc.is_method() {
match ref_ty.kind() {
ty::Param(param) if param.name == kw::SelfUpper => {
format!("&{}{}self", reg, mutability.prefix_str())
@@ -427,7 +427,7 @@ fn fn_sig_suggestion<'tcx>(
}
}
_ => {
if assoc.fn_has_self_parameter && i == 0 {
if assoc.is_method() && i == 0 {
format!("self: {ty}")
} else {
format!("_: {ty}")
@@ -489,7 +489,7 @@ fn suggestion_signature<'tcx>(
);
match assoc.kind {
ty::AssocKind::Fn => fn_sig_suggestion(
ty::AssocKind::Fn { .. } => fn_sig_suggestion(
tcx,
tcx.liberate_late_bound_regions(
assoc.def_id,
@@ -499,14 +499,14 @@ fn suggestion_signature<'tcx>(
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
assoc,
),
ty::AssocKind::Type => {
ty::AssocKind::Type { .. } => {
let (generics, where_clauses) = bounds_from_generic_predicates(
tcx,
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
);
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name())
}
ty::AssocKind::Const => {
ty::AssocKind::Const { name } => {
let ty = tcx.type_of(assoc.def_id).instantiate_identity();
let val = tcx
.infer_ctxt()
@@ -514,7 +514,7 @@ fn suggestion_signature<'tcx>(
.err_ctxt()
.ty_kind_suggestion(tcx.param_env(assoc.def_id), ty)
.unwrap_or_else(|| "value".to_string());
format!("const {}: {} = {};", assoc.name, ty, val)
format!("const {}: {} = {};", name, ty, val)
}
}
}

View File

@@ -408,7 +408,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
let gat_def_id = gat_item.def_id.expect_local();
let gat_item = tcx.associated_item(gat_def_id);
// If this item is not an assoc ty, or has no args, then it's not a GAT
if gat_item.kind != ty::AssocKind::Type {
if !gat_item.is_type() {
continue;
}
let gat_generics = tcx.generics_of(gat_def_id);
@@ -432,7 +432,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
let item_required_bounds = match tcx.associated_item(item_def_id).kind {
// In our example, this corresponds to `into_iter` method
ty::AssocKind::Fn => {
ty::AssocKind::Fn { .. } => {
// For methods, we check the function signature's return type for any GATs
// to constrain. In the `into_iter` case, we see that the return type
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
@@ -453,7 +453,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
)
}
// In our example, this corresponds to the `Iter` and `Item` associated types
ty::AssocKind::Type => {
ty::AssocKind::Type { .. } => {
// If our associated item is a GAT with missing bounds, add them to
// the param-env here. This allows this GAT to propagate missing bounds
// to other GATs.
@@ -474,7 +474,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
gat_generics,
)
}
ty::AssocKind::Const => None,
ty::AssocKind::Const { .. } => None,
};
if let Some(item_required_bounds) = item_required_bounds {
@@ -1076,7 +1076,7 @@ fn check_associated_item(
};
match item.kind {
ty::AssocKind::Const => {
ty::AssocKind::Const { .. } => {
let ty = tcx.type_of(item.def_id).instantiate_identity();
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
wfcx.register_wf_obligation(span, loc, ty.into());
@@ -1089,7 +1089,7 @@ fn check_associated_item(
);
Ok(())
}
ty::AssocKind::Fn => {
ty::AssocKind::Fn { .. } => {
let sig = tcx.fn_sig(item.def_id).instantiate_identity();
let hir_sig = sig_if_method.expect("bad signature for method");
check_fn_or_method(
@@ -1101,7 +1101,7 @@ fn check_associated_item(
);
check_method_receiver(wfcx, hir_sig, item, self_ty)
}
ty::AssocKind::Type => {
ty::AssocKind::Type { .. } => {
if let ty::AssocItemContainer::Trait = item.container {
check_associated_type_bounds(wfcx, item, span)
}
@@ -1716,7 +1716,7 @@ fn check_method_receiver<'tcx>(
) -> Result<(), ErrorGuaranteed> {
let tcx = wfcx.tcx();
if !method.fn_has_self_parameter {
if !method.is_method() {
return Ok(());
}