Skip to content

Commit 384d26f

Browse files
committed
Auto merge of #121800 - GuillaumeGomez:rollup-wob2qcz, r=GuillaumeGomez
Rollup of 10 pull requests Successful merges: - #118217 (Document which methods on `f64` are precise) - #119748 (Increase visibility of `join_path` and `split_paths`) - #121412 (platform docs: clarify hexagon-unknown-none-elf example, add hexagon-unknown-linux-musl) - #121654 (Fix `async Fn` confirmation for `FnDef`/`FnPtr`/`Closure` types) - #121700 (CFI: Don't compress user-defined builtin types) - #121765 (add platform-specific function to get the error number for HermitOS) - #121781 (bootstrap/format: send larger batches to rustfmt) - #121788 (bootstrap: fix clap deprecated warnings) - #121792 (Improve renaming suggestion when item starts with underscore) - #121793 (Document which methods on `f32` are precise) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 71a7b66 + bc23b84 commit 384d26f

File tree

28 files changed

+891
-144
lines changed

28 files changed

+891
-144
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -1640,9 +1640,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
16401640

16411641
[[package]]
16421642
name = "hermit-abi"
1643-
version = "0.3.6"
1643+
version = "0.3.9"
16441644
source = "registry+https://github.com/rust-lang/crates.io-index"
1645-
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
1645+
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
16461646
dependencies = [
16471647
"compiler_builtins",
16481648
"rustc-std-workspace-alloc",

compiler/rustc_mir_transform/src/shim.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
3737
}
3838
ty::InstanceDef::FnPtrShim(def_id, ty) => {
3939
let trait_ = tcx.trait_of_item(def_id).unwrap();
40-
let adjustment = match tcx.fn_trait_kind_from_def_id(trait_) {
40+
// Supports `Fn` or `async Fn` traits.
41+
let adjustment = match tcx
42+
.fn_trait_kind_from_def_id(trait_)
43+
.or_else(|| tcx.async_fn_trait_kind_from_def_id(trait_))
44+
{
4145
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
4246
Some(ty::ClosureKind::Fn) => Adjustment::Deref { source: DerefSource::ImmRef },
4347
Some(ty::ClosureKind::FnMut) => Adjustment::Deref { source: DerefSource::MutRef },

compiler/rustc_resolve/src/diagnostics.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1585,9 +1585,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15851585
{
15861586
// When the suggested binding change would be from `x` to `_x`, suggest changing the
15871587
// original binding definition instead. (#60164)
1588-
(span, snippet, ", consider changing it")
1588+
let post = format!(", consider renaming `{}` into `{snippet}`", suggestion.candidate);
1589+
(span, snippet, post)
15891590
} else {
1590-
(span, suggestion.candidate.to_string(), "")
1591+
(span, suggestion.candidate.to_string(), String::new())
15911592
};
15921593
let msg = match suggestion.target {
15931594
SuggestionTarget::SimilarlyNamed => format!(

compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,20 @@ fn encode_ty<'tcx>(
546546
if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) {
547547
// Use user-defined CFI encoding for type
548548
if let Some(value_str) = cfi_encoding.value_str() {
549-
if !value_str.to_string().trim().is_empty() {
550-
s.push_str(value_str.to_string().trim());
549+
let value_str = value_str.to_string();
550+
let str = value_str.trim();
551+
if !str.is_empty() {
552+
s.push_str(str);
553+
// Don't compress user-defined builtin types (see
554+
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and
555+
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression).
556+
let builtin_types = [
557+
"v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y",
558+
"n", "o", "f", "d", "e", "g", "z",
559+
];
560+
if !builtin_types.contains(&str) {
561+
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
562+
}
551563
} else {
552564
#[allow(
553565
rustc::diagnostic_outside_of_impl,
@@ -563,7 +575,6 @@ fn encode_ty<'tcx>(
563575
} else {
564576
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
565577
}
566-
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
567578
} else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() {
568579
// For cross-language LLVM CFI support, the encoding must be compatible at the FFI
569580
// boundary. For instance:

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

+156-45
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,58 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
281281
}
282282

283283
// Coroutine-closures don't implement `Fn` traits the normal way.
284-
ty::CoroutineClosure(..) => Err(NoSolution),
284+
// Instead, they always implement `FnOnce`, but only implement
285+
// `FnMut`/`Fn` if they capture no upvars, since those may borrow
286+
// from the closure.
287+
ty::CoroutineClosure(def_id, args) => {
288+
let args = args.as_coroutine_closure();
289+
let kind_ty = args.kind_ty();
290+
let sig = args.coroutine_closure_sig().skip_binder();
291+
292+
let coroutine_ty = if let Some(closure_kind) = kind_ty.to_opt_closure_kind() {
293+
if !closure_kind.extends(goal_kind) {
294+
return Err(NoSolution);
295+
}
296+
297+
// If `Fn`/`FnMut`, we only implement this goal if we
298+
// have no captures.
299+
let no_borrows = match args.tupled_upvars_ty().kind() {
300+
ty::Tuple(tys) => tys.is_empty(),
301+
ty::Error(_) => false,
302+
_ => bug!("tuple_fields called on non-tuple"),
303+
};
304+
if closure_kind != ty::ClosureKind::FnOnce && !no_borrows {
305+
return Err(NoSolution);
306+
}
307+
308+
coroutine_closure_to_certain_coroutine(
309+
tcx,
310+
goal_kind,
311+
// No captures by ref, so this doesn't matter.
312+
tcx.lifetimes.re_static,
313+
def_id,
314+
args,
315+
sig,
316+
)
317+
} else {
318+
// Closure kind is not yet determined, so we return ambiguity unless
319+
// the expected kind is `FnOnce` as that is always implemented.
320+
if goal_kind != ty::ClosureKind::FnOnce {
321+
return Ok(None);
322+
}
323+
324+
coroutine_closure_to_ambiguous_coroutine(
325+
tcx,
326+
goal_kind, // No captures by ref, so this doesn't matter.
327+
tcx.lifetimes.re_static,
328+
def_id,
329+
args,
330+
sig,
331+
)
332+
};
333+
334+
Ok(Some(args.coroutine_closure_sig().rebind((sig.tupled_inputs_ty, coroutine_ty))))
335+
}
285336

286337
ty::Bool
287338
| ty::Char
@@ -313,6 +364,19 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
313364
}
314365
}
315366

367+
/// Relevant types for an async callable, including its inputs, output,
368+
/// and the return type you get from awaiting the output.
369+
#[derive(Copy, Clone, Debug, TypeVisitable, TypeFoldable)]
370+
pub(in crate::solve) struct AsyncCallableRelevantTypes<'tcx> {
371+
pub tupled_inputs_ty: Ty<'tcx>,
372+
/// Type returned by calling the closure
373+
/// i.e. `f()`.
374+
pub output_coroutine_ty: Ty<'tcx>,
375+
/// Type returned by `await`ing the output
376+
/// i.e. `f().await`.
377+
pub coroutine_return_ty: Ty<'tcx>,
378+
}
379+
316380
// Returns a binder of the tupled inputs types, output type, and coroutine type
317381
// from a builtin coroutine-closure type. If we don't yet know the closure kind of
318382
// the coroutine-closure, emit an additional trait predicate for `AsyncFnKindHelper`
@@ -323,8 +387,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
323387
self_ty: Ty<'tcx>,
324388
goal_kind: ty::ClosureKind,
325389
env_region: ty::Region<'tcx>,
326-
) -> Result<(ty::Binder<'tcx, (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>)>, Vec<ty::Predicate<'tcx>>), NoSolution>
327-
{
390+
) -> Result<
391+
(ty::Binder<'tcx, AsyncCallableRelevantTypes<'tcx>>, Vec<ty::Predicate<'tcx>>),
392+
NoSolution,
393+
> {
328394
match *self_ty.kind() {
329395
ty::CoroutineClosure(def_id, args) => {
330396
let args = args.as_coroutine_closure();
@@ -335,24 +401,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
335401
if !closure_kind.extends(goal_kind) {
336402
return Err(NoSolution);
337403
}
338-
sig.to_coroutine_given_kind_and_upvars(
339-
tcx,
340-
args.parent_args(),
341-
tcx.coroutine_for_closure(def_id),
342-
goal_kind,
343-
env_region,
344-
args.tupled_upvars_ty(),
345-
args.coroutine_captures_by_ref_ty(),
404+
405+
coroutine_closure_to_certain_coroutine(
406+
tcx, goal_kind, env_region, def_id, args, sig,
346407
)
347408
} else {
348-
let async_fn_kind_trait_def_id =
349-
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
350-
let upvars_projection_def_id = tcx
351-
.associated_items(async_fn_kind_trait_def_id)
352-
.filter_by_name_unhygienic(sym::Upvars)
353-
.next()
354-
.unwrap()
355-
.def_id;
356409
// When we don't know the closure kind (and therefore also the closure's upvars,
357410
// which are computed at the same time), we must delay the computation of the
358411
// generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
@@ -363,38 +416,23 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
363416
nested.push(
364417
ty::TraitRef::new(
365418
tcx,
366-
async_fn_kind_trait_def_id,
419+
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None),
367420
[kind_ty, Ty::from_closure_kind(tcx, goal_kind)],
368421
)
369422
.to_predicate(tcx),
370423
);
371-
let tupled_upvars_ty = Ty::new_projection(
372-
tcx,
373-
upvars_projection_def_id,
374-
[
375-
ty::GenericArg::from(kind_ty),
376-
Ty::from_closure_kind(tcx, goal_kind).into(),
377-
env_region.into(),
378-
sig.tupled_inputs_ty.into(),
379-
args.tupled_upvars_ty().into(),
380-
args.coroutine_captures_by_ref_ty().into(),
381-
],
382-
);
383-
sig.to_coroutine(
384-
tcx,
385-
args.parent_args(),
386-
Ty::from_closure_kind(tcx, goal_kind),
387-
tcx.coroutine_for_closure(def_id),
388-
tupled_upvars_ty,
424+
425+
coroutine_closure_to_ambiguous_coroutine(
426+
tcx, goal_kind, env_region, def_id, args, sig,
389427
)
390428
};
391429

392430
Ok((
393-
args.coroutine_closure_sig().rebind((
394-
sig.tupled_inputs_ty,
395-
sig.return_ty,
396-
coroutine_ty,
397-
)),
431+
args.coroutine_closure_sig().rebind(AsyncCallableRelevantTypes {
432+
tupled_inputs_ty: sig.tupled_inputs_ty,
433+
output_coroutine_ty: coroutine_ty,
434+
coroutine_return_ty: sig.return_ty,
435+
}),
398436
nested,
399437
))
400438
}
@@ -418,7 +456,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
418456
.def_id;
419457
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
420458
Ok((
421-
bound_sig.rebind((Ty::new_tup(tcx, sig.inputs()), sig.output(), future_output_ty)),
459+
bound_sig.rebind(AsyncCallableRelevantTypes {
460+
tupled_inputs_ty: Ty::new_tup(tcx, sig.inputs()),
461+
output_coroutine_ty: sig.output(),
462+
coroutine_return_ty: future_output_ty,
463+
}),
422464
nested,
423465
))
424466
}
@@ -469,7 +511,14 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
469511
.unwrap()
470512
.def_id;
471513
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
472-
Ok((bound_sig.rebind((sig.inputs()[0], sig.output(), future_output_ty)), nested))
514+
Ok((
515+
bound_sig.rebind(AsyncCallableRelevantTypes {
516+
tupled_inputs_ty: sig.inputs()[0],
517+
output_coroutine_ty: sig.output(),
518+
coroutine_return_ty: future_output_ty,
519+
}),
520+
nested,
521+
))
473522
}
474523

475524
ty::Bool
@@ -502,6 +551,68 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
502551
}
503552
}
504553

554+
/// Given a coroutine-closure, project to its returned coroutine when we are *certain*
555+
/// that the closure's kind is compatible with the goal.
556+
fn coroutine_closure_to_certain_coroutine<'tcx>(
557+
tcx: TyCtxt<'tcx>,
558+
goal_kind: ty::ClosureKind,
559+
goal_region: ty::Region<'tcx>,
560+
def_id: DefId,
561+
args: ty::CoroutineClosureArgs<'tcx>,
562+
sig: ty::CoroutineClosureSignature<'tcx>,
563+
) -> Ty<'tcx> {
564+
sig.to_coroutine_given_kind_and_upvars(
565+
tcx,
566+
args.parent_args(),
567+
tcx.coroutine_for_closure(def_id),
568+
goal_kind,
569+
goal_region,
570+
args.tupled_upvars_ty(),
571+
args.coroutine_captures_by_ref_ty(),
572+
)
573+
}
574+
575+
/// Given a coroutine-closure, project to its returned coroutine when we are *not certain*
576+
/// that the closure's kind is compatible with the goal, and therefore also don't know
577+
/// yet what the closure's upvars are.
578+
///
579+
/// Note that we do not also push a `AsyncFnKindHelper` goal here.
580+
fn coroutine_closure_to_ambiguous_coroutine<'tcx>(
581+
tcx: TyCtxt<'tcx>,
582+
goal_kind: ty::ClosureKind,
583+
goal_region: ty::Region<'tcx>,
584+
def_id: DefId,
585+
args: ty::CoroutineClosureArgs<'tcx>,
586+
sig: ty::CoroutineClosureSignature<'tcx>,
587+
) -> Ty<'tcx> {
588+
let async_fn_kind_trait_def_id = tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
589+
let upvars_projection_def_id = tcx
590+
.associated_items(async_fn_kind_trait_def_id)
591+
.filter_by_name_unhygienic(sym::Upvars)
592+
.next()
593+
.unwrap()
594+
.def_id;
595+
let tupled_upvars_ty = Ty::new_projection(
596+
tcx,
597+
upvars_projection_def_id,
598+
[
599+
ty::GenericArg::from(args.kind_ty()),
600+
Ty::from_closure_kind(tcx, goal_kind).into(),
601+
goal_region.into(),
602+
sig.tupled_inputs_ty.into(),
603+
args.tupled_upvars_ty().into(),
604+
args.coroutine_captures_by_ref_ty().into(),
605+
],
606+
);
607+
sig.to_coroutine(
608+
tcx,
609+
args.parent_args(),
610+
Ty::from_closure_kind(tcx, goal_kind),
611+
tcx.coroutine_for_closure(def_id),
612+
tupled_upvars_ty,
613+
)
614+
}
615+
505616
/// Assemble a list of predicates that would be present on a theoretical
506617
/// user impl for an object type. These predicates must be checked any time
507618
/// we assemble a built-in object candidate for an object type, since they

0 commit comments

Comments
 (0)