Skip to content
Closed
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7b3ef13
Fix a typo in the alloc::string::String docs
reedwoodruff Mar 18, 2024
25d0601
fix(bootstrap/dist): use versioned dirs when vendoring
lovesegfault Mar 22, 2024
9685161
Update stdarch submodule
dpaoliello Mar 22, 2024
c31b217
Add regression tests for #101903
ShoyuVanilla Mar 23, 2024
8dc10da
Port backtrace dylib-dep test to a ui test
jieyouxu Mar 23, 2024
58e2ad3
Amended wording
reedwoodruff Mar 24, 2024
3010fa9
In `pretty_print_type()`, print `async fn` futures' paths instead of …
kpreid Mar 23, 2024
95f268e
Update books
rustbot Mar 25, 2024
99fbc6f
Instance is Copy
compiler-errors Mar 25, 2024
d94f657
extend doc comment for reachability set computation
RalfJung Mar 22, 2024
5f95fc1
add test for Compiler panic using fn_traits #81974
matthiaskrgr Mar 25, 2024
6fe5555
add test for ICE Where clause `Binder(..)` was applicable to `Obligat…
matthiaskrgr Mar 25, 2024
a3c2d75
add test for ICE: failed to get layout for [type error] #92979
matthiaskrgr Mar 25, 2024
bc72b25
Rollup merge of #122707 - reedwoodruff:string_docs_typo, r=workingjub…
workingjubilee Mar 25, 2024
2532622
Rollup merge of #122769 - RalfJung:reachable, r=tmiasko
workingjubilee Mar 25, 2024
329c63b
Rollup merge of #122892 - lovesegfault:versioned-vendor, r=onur-ozkan
workingjubilee Mar 25, 2024
a62c655
Rollup merge of #122896 - dpaoliello:stdarch, r=Amanieu
workingjubilee Mar 25, 2024
d813c2d
Rollup merge of #122923 - kpreid:print-async-def, r=compiler-errors
workingjubilee Mar 25, 2024
e8c9042
Rollup merge of #122950 - ShoyuVanilla:issue-101903, r=compiler-errors
workingjubilee Mar 25, 2024
0aa8ed8
Rollup merge of #122958 - jieyouxu:port-backtrace-dylib-dep, r=workin…
workingjubilee Mar 25, 2024
1ba8e45
Rollup merge of #123039 - rustbot:docs-update, r=ehuss
workingjubilee Mar 25, 2024
2f3bfa6
Rollup merge of #123044 - compiler-errors:instance, r=oli-obk
workingjubilee Mar 25, 2024
ed871e2
Rollup merge of #123051 - matthiaskrgr:casetest, r=workingjubilee
workingjubilee Mar 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1630,7 +1630,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
}

let typeid = if let Some(instance) = instance {
typeid_for_instance(self.tcx, &instance, options)
typeid_for_instance(self.tcx, instance, options)
} else {
typeid_for_fnabi(self.tcx, fn_abi, options)
};
@@ -1678,7 +1678,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
}

let kcfi_typeid = if let Some(instance) = instance {
kcfi_typeid_for_instance(self.tcx, &instance, options)
kcfi_typeid_for_instance(self.tcx, instance, options)
} else {
kcfi_typeid_for_fnabi(self.tcx, fn_abi, options)
};
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
@@ -141,17 +141,17 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {

if self.tcx.sess.is_sanitizer_cfi_enabled() {
if let Some(instance) = instance {
let typeid = typeid_for_instance(self.tcx, &instance, TypeIdOptions::empty());
let typeid = typeid_for_instance(self.tcx, instance, TypeIdOptions::empty());
self.set_type_metadata(llfn, typeid);
let typeid =
typeid_for_instance(self.tcx, &instance, TypeIdOptions::GENERALIZE_POINTERS);
typeid_for_instance(self.tcx, instance, TypeIdOptions::GENERALIZE_POINTERS);
self.add_type_metadata(llfn, typeid);
let typeid =
typeid_for_instance(self.tcx, &instance, TypeIdOptions::NORMALIZE_INTEGERS);
typeid_for_instance(self.tcx, instance, TypeIdOptions::NORMALIZE_INTEGERS);
self.add_type_metadata(llfn, typeid);
let typeid = typeid_for_instance(
self.tcx,
&instance,
instance,
TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS,
);
self.add_type_metadata(llfn, typeid);
@@ -182,7 +182,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
}

if let Some(instance) = instance {
let kcfi_typeid = kcfi_typeid_for_instance(self.tcx, &instance, options);
let kcfi_typeid = kcfi_typeid_for_instance(self.tcx, instance, options);
self.set_kcfi_type_metadata(llfn, kcfi_typeid);
} else {
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
@@ -335,7 +335,7 @@ impl<'tcx> InstanceDef<'tcx> {

fn fmt_instance(
f: &mut fmt::Formatter<'_>,
instance: &Instance<'_>,
instance: Instance<'_>,
type_length: Option<rustc_session::Limit>,
) -> fmt::Result {
ty::tls::with(|tcx| {
@@ -369,17 +369,17 @@ fn fmt_instance(
}
}

pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
pub struct ShortInstance<'tcx>(pub Instance<'tcx>, pub usize);

impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
impl<'tcx> fmt::Display for ShortInstance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_instance(f, self.0, Some(rustc_session::Limit(self.1)))
}
}

impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_instance(f, self, None)
fmt_instance(f, *self, None)
}
}

18 changes: 13 additions & 5 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
@@ -804,7 +804,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
}
ty::Str => p!("str"),
ty::Coroutine(did, args) => {
p!(write("{{"));
p!("{{");
let coroutine_kind = self.tcx().coroutine_kind(did).unwrap();
let should_print_movability = self.should_print_verbose()
|| matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_));
@@ -818,17 +818,25 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {

if !self.should_print_verbose() {
p!(write("{}", coroutine_kind));
// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let span = self.tcx().def_span(did);
if coroutine_kind.is_fn_like() {
// If we are printing an `async fn` coroutine type, then give the path
// of the fn, instead of its span, because that will in most cases be
// more helpful for the reader than just a source location.
//
// This will look like:
// {async fn body of some_fn()}
let did_of_the_fn_item = self.tcx().parent(did);
p!(" of ", print_def_path(did_of_the_fn_item, args), "()");
} else if let Some(local_did) = did.as_local() {
let span = self.tcx().def_span(local_did);
p!(write(
"@{}",
// This may end up in stderr diagnostics but it may also be emitted
// into MIR. Hence we use the remapped path if available
self.tcx().sess.source_map().span_to_embeddable_string(span)
));
} else {
p!(write("@"), print_def_path(did, args));
p!("@", print_def_path(did, args));
}
} else {
p!(print_def_path(did, args));
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ impl<'tcx> Inliner<'tcx> {
caller_body: &mut Body<'tcx>,
callsite: &CallSite<'tcx>,
) -> Result<std::ops::Range<BasicBlock>, &'static str> {
self.check_mir_is_available(caller_body, &callsite.callee)?;
self.check_mir_is_available(caller_body, callsite.callee)?;

let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id());
let cross_crate_inlinable = self.tcx.cross_crate_inlinable(callsite.callee.def_id());
@@ -298,7 +298,7 @@ impl<'tcx> Inliner<'tcx> {
fn check_mir_is_available(
&self,
caller_body: &Body<'tcx>,
callee: &Instance<'tcx>,
callee: Instance<'tcx>,
) -> Result<(), &'static str> {
let caller_def_id = caller_body.source.def_id();
let callee_def_id = callee.def_id();
@@ -354,7 +354,7 @@ impl<'tcx> Inliner<'tcx> {

// If we know for sure that the function we're calling will itself try to
// call us, then we avoid inlining that function.
if self.tcx.mir_callgraph_reachable((*callee, caller_def_id.expect_local())) {
if self.tcx.mir_callgraph_reachable((callee, caller_def_id.expect_local())) {
return Err("caller might be reachable from callee (query cycle avoidance)");
}

38 changes: 19 additions & 19 deletions compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
@@ -397,7 +397,7 @@ fn collect_items_rec<'tcx>(
let instance = Instance::mono(tcx, def_id);

// Sanity check whether this ended up being collected accidentally
debug_assert!(should_codegen_locally(tcx, &instance));
debug_assert!(should_codegen_locally(tcx, instance));

let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() };
// Nested statics have no type.
@@ -429,7 +429,7 @@ fn collect_items_rec<'tcx>(
}
MonoItem::Fn(instance) => {
// Sanity check whether this ended up being collected accidentally
debug_assert!(should_codegen_locally(tcx, &instance));
debug_assert!(should_codegen_locally(tcx, instance));

// Keep track of the monomorphization recursion depth
recursion_depth_reset = Some(check_recursion_limit(
@@ -474,7 +474,7 @@ fn collect_items_rec<'tcx>(
}
hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
let instance = Instance::mono(tcx, *def_id);
if should_codegen_locally(tcx, &instance) {
if should_codegen_locally(tcx, instance) {
trace!("collecting static {:?}", def_id);
used_items.push(dummy_spanned(MonoItem::Static(*def_id)));
}
@@ -557,7 +557,7 @@ fn collect_items_rec<'tcx>(
/// If the type name is longer than before+after, it will be written to a file.
fn shrunk_instance_name<'tcx>(
tcx: TyCtxt<'tcx>,
instance: &Instance<'tcx>,
instance: Instance<'tcx>,
) -> (String, Option<PathBuf>) {
let s = instance.to_string();

@@ -603,7 +603,7 @@ fn check_recursion_limit<'tcx>(
if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
let def_span = tcx.def_span(def_id);
let def_path_str = tcx.def_path_str(def_id);
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
let (shrunk, written_to_path) = shrunk_instance_name(tcx, instance);
let mut path = PathBuf::new();
let was_written = if let Some(written_to_path) = written_to_path {
path = written_to_path;
@@ -645,7 +645,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
//
// Bail out in these cases to avoid that bad user experience.
if !tcx.type_length_limit().value_within_limit(type_length) {
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
let (shrunk, written_to_path) = shrunk_instance_name(tcx, instance);
let span = tcx.def_span(instance.def_id());
let mut path = PathBuf::new();
let was_written = if let Some(path2) = written_to_path {
@@ -892,7 +892,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
if let ty::Closure(def_id, args) = *source_ty.kind() {
let instance =
Instance::resolve_closure(self.tcx, def_id, args, ty::ClosureKind::FnOnce);
if should_codegen_locally(self.tcx, &instance) {
if should_codegen_locally(self.tcx, instance) {
self.used_items.push(create_fn_mono_item(self.tcx, instance, span));
}
} else {
@@ -902,7 +902,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
mir::Rvalue::ThreadLocalRef(def_id) => {
assert!(self.tcx.is_thread_local_static(def_id));
let instance = Instance::mono(self.tcx, def_id);
if should_codegen_locally(self.tcx, &instance) {
if should_codegen_locally(self.tcx, instance) {
trace!("collecting thread-local static {:?}", def_id);
self.used_items.push(respan(span, MonoItem::Static(def_id)));
}
@@ -929,7 +929,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
let tcx = self.tcx;
let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| {
let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
if should_codegen_locally(tcx, &instance) {
if should_codegen_locally(tcx, instance) {
this.used_items.push(create_fn_mono_item(tcx, instance, source));
}
};
@@ -962,7 +962,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
}
mir::InlineAsmOperand::SymStatic { def_id } => {
let instance = Instance::mono(self.tcx, def_id);
if should_codegen_locally(self.tcx, &instance) {
if should_codegen_locally(self.tcx, instance) {
trace!("collecting asm sym static {:?}", def_id);
self.used_items.push(respan(source, MonoItem::Static(def_id)));
}
@@ -1051,7 +1051,7 @@ fn visit_instance_use<'tcx>(
output: &mut MonoItems<'tcx>,
) {
debug!("visit_item_use({:?}, is_direct_call={:?})", instance, is_direct_call);
if !should_codegen_locally(tcx, &instance) {
if !should_codegen_locally(tcx, instance) {
return;
}
if let ty::InstanceDef::Intrinsic(def_id) = instance.def {
@@ -1063,13 +1063,13 @@ fn visit_instance_use<'tcx>(
// codegen a call to that function without generating code for the function itself.
let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap();
let panic_instance = Instance::mono(tcx, def_id);
if should_codegen_locally(tcx, &panic_instance) {
if should_codegen_locally(tcx, panic_instance) {
output.push(create_fn_mono_item(tcx, panic_instance, source));
}
} else if tcx.has_attr(def_id, sym::rustc_intrinsic) {
// Codegen the fallback body of intrinsics with fallback bodies
let instance = ty::Instance::new(def_id, instance.args);
if should_codegen_locally(tcx, &instance) {
if should_codegen_locally(tcx, instance) {
output.push(create_fn_mono_item(tcx, instance, source));
}
}
@@ -1107,7 +1107,7 @@ fn visit_instance_use<'tcx>(

/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
/// can just link to the upstream crate and therefore don't need a mono item.
pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
return true;
};
@@ -1304,7 +1304,7 @@ fn create_mono_items_for_vtable_methods<'tcx>(
None
}
VtblEntry::Method(instance) => {
Some(*instance).filter(|instance| should_codegen_locally(tcx, instance))
Some(*instance).filter(|instance| should_codegen_locally(tcx, *instance))
}
})
.map(|item| create_fn_mono_item(tcx, item, source));
@@ -1321,7 +1321,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
let instance = Instance::mono(tcx, def_id);
if should_codegen_locally(tcx, &instance) {
if should_codegen_locally(tcx, instance) {
trace!("collecting static {:?}", def_id);
output.push(dummy_spanned(MonoItem::Static(def_id)));
}
@@ -1339,7 +1339,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
}
}
GlobalAlloc::Function(fn_instance) => {
if should_codegen_locally(tcx, &fn_instance) {
if should_codegen_locally(tcx, fn_instance) {
trace!("collecting {:?} with {:#?}", alloc_id, fn_instance);
output.push(create_fn_mono_item(tcx, fn_instance, DUMMY_SP));
}
@@ -1474,7 +1474,7 @@ fn visit_mentioned_item<'tcx>(
if let ty::Closure(def_id, args) = *source_ty.kind() {
let instance =
Instance::resolve_closure(tcx, def_id, args, ty::ClosureKind::FnOnce);
if should_codegen_locally(tcx, &instance) {
if should_codegen_locally(tcx, instance) {
output.push(create_fn_mono_item(tcx, instance, span));
}
} else {
@@ -1736,7 +1736,7 @@ fn create_mono_items_for_default_impls<'tcx>(
let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args);

let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP);
if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, &instance) {
if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, instance) {
output.push(mono_item);
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_monomorphize/src/lib.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
!instance.def_id().is_local()
&& tcx.is_compiler_builtins(LOCAL_CRATE)
&& tcx.codegen_fn_attrs(instance.def_id()).link_name.is_none()
&& !should_codegen_locally(tcx, &instance)
&& !should_codegen_locally(tcx, instance)
}

pub fn provide(providers: &mut Providers) {
72 changes: 49 additions & 23 deletions compiler/rustc_passes/src/reachable.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// Finds items that are externally reachable, to determine which items
// need to have their metadata (and possibly their AST) serialized.
// All items that can be referred to through an exported name are
// reachable, and when a reachable thing is inline or generic, it
// makes all other generics or inline functions that it references
// reachable as well.
//! Finds local items that are externally reachable, which means that other crates need access to
//! their compiled machine code or their MIR.
//!
//! An item is "externally reachable" if it is relevant for other crates. This obviously includes
//! all public items. However, some of these items cannot be compiled to machine code (because they
//! are generic), and for some the machine code is not sufficient (because we want to cross-crate
//! inline them). These items "need cross-crate MIR". When a reachable function `f` needs
//! cross-crate MIR, then all the functions it calls also become reachable, as they will be
//! necessary to use the MIR of `f` from another crate. Furthermore, an item can become "externally
//! reachable" by having a `const`/`const fn` return a pointer to that item, so we also need to
//! recurse into reachable `const`/`const fn`.
use hir::def_id::LocalDefIdSet;
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -21,7 +26,9 @@ use rustc_privacy::DefIdVisitor;
use rustc_session::config::CrateType;
use rustc_target::spec::abi::Abi;

fn item_might_be_inlined(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
/// Determines whether this item is recursive for reachability. See `is_recursively_reachable_local`
/// below for details.
fn recursively_reachable(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
tcx.generics_of(def_id).requires_monomorphization(tcx)
|| tcx.cross_crate_inlinable(def_id)
|| tcx.is_const_fn(def_id)
@@ -54,12 +61,20 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
let res = match expr.kind {
hir::ExprKind::Path(ref qpath) => {
// This covers fn ptr casts but also "non-method" calls.
Some(self.typeck_results().qpath_res(qpath, expr.hir_id))
}
hir::ExprKind::MethodCall(..) => self
.typeck_results()
.type_dependent_def(expr.hir_id)
.map(|(kind, def_id)| Res::Def(kind, def_id)),
hir::ExprKind::MethodCall(..) => {
// Method calls don't involve a full "path", so we need to determine the callee
// based on the receiver type.
// If this is a method call on a generic type, we might not be able to find the
// callee. That's why `reachable_set` also adds all potential callees for such
// calls, i.e. all trait impl items, to the reachable set. So here we only worry
// about the calls we can identify.
self.typeck_results()
.type_dependent_def(expr.hir_id)
.map(|(kind, def_id)| Res::Def(kind, def_id))
}
hir::ExprKind::Closure(&hir::Closure { def_id, .. }) => {
self.reachable_symbols.insert(def_id);
None
@@ -96,16 +111,24 @@ impl<'tcx> ReachableContext<'tcx> {
.expect("`ReachableContext::typeck_results` called outside of body")
}

// Returns true if the given def ID represents a local item that is
// eligible for inlining and false otherwise.
fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
/// Returns true if the given def ID represents a local item that is recursive for reachability,
/// i.e. whether everything mentioned in here also needs to be considered reachable.
///
/// There are two reasons why an item may be recursively reachable:
/// - It needs cross-crate MIR (see the module-level doc comment above).
/// - It is a `const` or `const fn`. This is *not* because we need the MIR to interpret them
/// (MIR for const-eval and MIR for codegen is separate, and MIR for const-eval is always
/// encoded). Instead, it is because `const fn` can create `fn()` pointers to other items
/// which end up in the evaluated result of the constant and can then be called from other
/// crates. Those items must be considered reachable.
fn is_recursively_reachable_local(&self, def_id: DefId) -> bool {
let Some(def_id) = def_id.as_local() else {
return false;
};

match self.tcx.hir_node_by_def_id(def_id) {
Node::Item(item) => match item.kind {
hir::ItemKind::Fn(..) => item_might_be_inlined(self.tcx, def_id.into()),
hir::ItemKind::Fn(..) => recursively_reachable(self.tcx, def_id.into()),
_ => false,
},
Node::TraitItem(trait_method) => match trait_method.kind {
@@ -117,7 +140,7 @@ impl<'tcx> ReachableContext<'tcx> {
Node::ImplItem(impl_item) => match impl_item.kind {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Fn(..) => {
item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id())
recursively_reachable(self.tcx, impl_item.hir_id().owner.to_def_id())
}
hir::ImplItemKind::Type(_) => false,
},
@@ -174,7 +197,7 @@ impl<'tcx> ReachableContext<'tcx> {
Node::Item(item) => {
match item.kind {
hir::ItemKind::Fn(.., body) => {
if item_might_be_inlined(self.tcx, item.owner_id.into()) {
if recursively_reachable(self.tcx, item.owner_id.into()) {
self.visit_nested_body(body);
}
}
@@ -228,7 +251,7 @@ impl<'tcx> ReachableContext<'tcx> {
self.visit_nested_body(body);
}
hir::ImplItemKind::Fn(_, body) => {
if item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id()) {
if recursively_reachable(self.tcx, impl_item.hir_id().owner.to_def_id()) {
self.visit_nested_body(body)
}
}
@@ -316,7 +339,7 @@ impl<'tcx> ReachableContext<'tcx> {
self.worklist.push(def_id);
}
_ => {
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
if self.is_recursively_reachable_local(def_id.to_def_id()) {
self.worklist.push(def_id);
} else {
self.reachable_symbols.insert(def_id);
@@ -394,6 +417,7 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
}

/// See module-level doc comment above.
fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
let effective_visibilities = &tcx.effective_visibilities(());

@@ -427,14 +451,16 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet {
}
}
{
// Some methods from non-exported (completely private) trait impls still have to be
// reachable if they are called from inlinable code. Generally, it's not known until
// monomorphization if a specific trait impl item can be reachable or not. So, we
// conservatively mark all of them as reachable.
// As explained above, we have to mark all functions called from reachable
// `item_might_be_inlined` items as reachable. The issue is, when those functions are
// generic and call a trait method, we have no idea where that call goes! So, we
// conservatively mark all trait impl items as reachable.
// FIXME: One possible strategy for pruning the reachable set is to avoid marking impl
// items of non-exported traits (or maybe all local traits?) unless their respective
// trait items are used from inlinable code through method call syntax or UFCS, or their
// trait is a lang item.
// (But if you implement this, don't forget to take into account that vtables can also
// make trait methods reachable!)
let crate_items = tcx.hir_crate_items(());

for id in crate_items.free_items() {
8 changes: 4 additions & 4 deletions compiler/rustc_symbol_mangling/src/typeid.rs
Original file line number Diff line number Diff line change
@@ -33,10 +33,10 @@ pub fn typeid_for_fnabi<'tcx>(
/// Returns a type metadata identifier for the specified Instance.
pub fn typeid_for_instance<'tcx>(
tcx: TyCtxt<'tcx>,
instance: &Instance<'tcx>,
instance: Instance<'tcx>,
options: TypeIdOptions,
) -> String {
typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options)
typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options)
}

/// Returns a KCFI type metadata identifier for the specified FnAbi.
@@ -55,12 +55,12 @@ pub fn kcfi_typeid_for_fnabi<'tcx>(
/// Returns a KCFI type metadata identifier for the specified Instance.
pub fn kcfi_typeid_for_instance<'tcx>(
tcx: TyCtxt<'tcx>,
instance: &Instance<'tcx>,
instance: Instance<'tcx>,
options: TypeIdOptions,
) -> u32 {
// A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
// xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
let mut hash: XxHash64 = Default::default();
hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options).as_bytes());
hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes());
hash.finish() as u32
}
2 changes: 1 addition & 1 deletion library/alloc/src/string.rs
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ use crate::vec::Vec;
/// # Representation
///
/// A `String` is made up of three components: a pointer to some bytes, a
/// length, and a capacity. The pointer points to an internal buffer `String`
/// length, and a capacity. The pointer points to the internal buffer which `String`
/// uses to store its data. The length is the number of bytes currently stored
/// in the buffer, and the capacity is the size of the buffer in bytes. As such,
/// the length will always be less than or equal to the capacity.
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -270,6 +270,7 @@
#![feature(arm_target_feature)]
#![feature(avx512_target_feature)]
#![feature(hexagon_target_feature)]
#![feature(loongarch_target_feature)]
#![feature(mips_target_feature)]
#![feature(powerpc_target_feature)]
#![feature(riscv_target_feature)]
2 changes: 1 addition & 1 deletion library/stdarch
Submodule stdarch updated 68 files
+1 −1 .cirrus.yml
+2 −2 .github/workflows/main.yml
+5 −3 .gitignore
+2 −1 Cargo.toml
+0 −16 ci/docker/wasm32-wasi/Dockerfile
+13 −0 ci/docker/wasm32-wasip1/Dockerfile
+350 −350 crates/core_arch/src/aarch64/neon/generated.rs
+28 −7 crates/core_arch/src/aarch64/neon/mod.rs
+29 −7 crates/core_arch/src/arm_shared/barrier/mod.rs
+34 −10 crates/core_arch/src/arm_shared/crc.rs
+56 −14 crates/core_arch/src/arm_shared/crypto.rs
+31 −5 crates/core_arch/src/arm_shared/hints.rs
+30 −5 crates/core_arch/src/arm_shared/mod.rs
+2,053 −2,039 crates/core_arch/src/arm_shared/neon/generated.rs
+1 −1 crates/core_arch/src/arm_shared/neon/load_tests.rs
+1,612 −427 crates/core_arch/src/arm_shared/neon/mod.rs
+1 −1 crates/core_arch/src/arm_shared/neon/shift_and_insert_tests.rs
+1 −1 crates/core_arch/src/arm_shared/neon/store_tests.rs
+49 −49 crates/core_arch/src/arm_shared/neon/table_lookup_tests.rs
+1 −1 crates/core_arch/src/arm_shared/test_support.rs
+1 −0 crates/core_arch/src/lib.rs
+7,027 −0 crates/core_arch/src/loongarch64/lasx/generated.rs
+21 −0 crates/core_arch/src/loongarch64/lasx/mod.rs
+14,690 −0 crates/core_arch/src/loongarch64/lasx/tests.rs
+57 −0 crates/core_arch/src/loongarch64/lasx/types.rs
+6,843 −0 crates/core_arch/src/loongarch64/lsx/generated.rs
+21 −0 crates/core_arch/src/loongarch64/lsx/mod.rs
+7,132 −0 crates/core_arch/src/loongarch64/lsx/tests.rs
+41 −0 crates/core_arch/src/loongarch64/lsx/types.rs
+9 −0 crates/core_arch/src/loongarch64/mod.rs
+24 −5 crates/core_arch/src/mod.rs
+3 −180 crates/core_arch/src/powerpc/altivec.rs
+185 −0 crates/core_arch/src/powerpc/macros.rs
+1 −2 crates/core_arch/src/powerpc/mod.rs
+5 −0 crates/core_arch/src/powerpc64/mod.rs
+156 −0 crates/core_arch/src/powerpc64/vsx.rs
+22 −0 crates/core_arch/src/wasm32/mod.rs
+28 −27 crates/core_arch/src/x86/avx.rs
+3 −3 crates/core_arch/src/x86/avx512f.rs
+9 −9 crates/core_arch/src/x86/sse.rs
+12 −11 crates/core_arch/src/x86/sse2.rs
+12 −12 crates/core_arch/src/x86/sse41.rs
+2 −1 crates/core_arch/src/x86_64/sse2.rs
+6 −6 crates/intrinsic-test/src/main.rs
+2 −1 crates/simd-test-macro/src/lib.rs
+1 −1 crates/std_detect/src/detect/arch/aarch64.rs
+15 −27 crates/std_detect/src/detect/arch/loongarch.rs
+1 −1 crates/std_detect/src/detect/arch/mod.rs
+3 −0 crates/std_detect/src/detect/arch/x86.rs
+2 −1 crates/std_detect/src/detect/mod.rs
+30 −9 crates/std_detect/src/detect/os/linux/loongarch.rs
+15 −7 crates/std_detect/src/detect/os/x86.rs
+6 −1 crates/std_detect/tests/cpu-detection.rs
+2 −0 crates/std_detect/tests/macro_trailing_commas.rs
+1 −0 crates/std_detect/tests/x86-specific.rs
+1 −1 crates/stdarch-gen-arm/Cargo.toml
+1 −1 crates/stdarch-gen-arm/README.md
+0 −0 crates/stdarch-gen-arm/neon.spec
+18 −12 crates/stdarch-gen-arm/src/main.rs
+10 −0 crates/stdarch-gen-loongarch/Cargo.toml
+33 −0 crates/stdarch-gen-loongarch/README.md
+3,685 −0 crates/stdarch-gen-loongarch/lasx.spec
+5,342 −0 crates/stdarch-gen-loongarch/lasxintrin.h
+3,585 −0 crates/stdarch-gen-loongarch/lsx.spec
+5,185 −0 crates/stdarch-gen-loongarch/lsxintrin.h
+1,525 −0 crates/stdarch-gen-loongarch/src/main.rs
+1 −1 crates/stdarch-test/src/disassembly.rs
+1 −1 crates/stdarch-test/src/lib.rs
1 change: 1 addition & 0 deletions src/bootstrap/src/core/build_steps/dist.rs
Original file line number Diff line number Diff line change
@@ -1003,6 +1003,7 @@ impl Step for PlainSourceTarball {
// Vendor all Cargo dependencies
let mut cmd = Command::new(&builder.initial_cargo);
cmd.arg("vendor")
.arg("--versioned-dirs")
.arg("--sync")
.arg(builder.src.join("./src/tools/cargo/Cargo.toml"))
.arg("--sync")
1 change: 1 addition & 0 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
@@ -3192,6 +3192,7 @@ impl Step for TestHelpers {
.opt_level(0)
.warnings(false)
.debug(false)
.flag("-g1") // needed to have line number tables
.file(builder.src.join("tests/auxiliary/rust_test_helpers.c"))
.compile("rust_test_helpers");
}
2 changes: 1 addition & 1 deletion src/doc/edition-guide
2 changes: 1 addition & 1 deletion src/doc/reference
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
Original file line number Diff line number Diff line change
@@ -9,15 +9,15 @@
storage_conflicts: BitMatrix(0x0) {},
} */

fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>, _2: &mut Context<'_>) -> Poll<()> {
fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _4;
let mut _0: std::task::Poll<()>;
let mut _3: ();
let mut _4: &mut std::task::Context<'_>;
let mut _5: u32;

bb0: {
_5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16})));
_5 = discriminant((*(_1.0: &mut {async fn body of a()})));
switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5];
}

@@ -29,7 +29,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>

bb2: {
_0 = Poll::<()>::Ready(move _3);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}))) = 1;
discriminant((*(_1.0: &mut {async fn body of a()}))) = 1;
return;
}

Original file line number Diff line number Diff line change
@@ -51,34 +51,34 @@
},
} */

fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, _2: &mut Context<'_>) -> Poll<()> {
fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _38;
let mut _0: std::task::Poll<()>;
let _3: ();
let mut _4: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _5: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _6: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _4: {async fn body of a()};
let mut _5: {async fn body of a()};
let mut _6: {async fn body of a()};
let mut _7: ();
let _8: ();
let mut _9: std::task::Poll<()>;
let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>;
let mut _11: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _12: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _10: std::pin::Pin<&mut {async fn body of a()}>;
let mut _11: &mut {async fn body of a()};
let mut _12: &mut {async fn body of a()};
let mut _13: &mut std::task::Context<'_>;
let mut _14: &mut std::task::Context<'_>;
let mut _15: &mut std::task::Context<'_>;
let mut _16: isize;
let mut _18: !;
let mut _19: &mut std::task::Context<'_>;
let mut _20: ();
let mut _21: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _22: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _23: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _21: {async fn body of a()};
let mut _22: {async fn body of a()};
let mut _23: {async fn body of a()};
let _24: ();
let mut _25: std::task::Poll<()>;
let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>;
let mut _27: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _28: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _26: std::pin::Pin<&mut {async fn body of a()}>;
let mut _27: &mut {async fn body of a()};
let mut _28: &mut {async fn body of a()};
let mut _29: &mut std::task::Context<'_>;
let mut _30: &mut std::task::Context<'_>;
let mut _31: &mut std::task::Context<'_>;
@@ -90,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
let mut _38: &mut std::task::Context<'_>;
let mut _39: u32;
scope 1 {
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
let _17: ();
scope 2 {
}
@@ -99,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
}
}
scope 4 {
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()});
let _33: ();
scope 5 {
}
@@ -109,7 +109,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
}

bb0: {
_39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})));
_39 = discriminant((*(_1.0: &mut {async fn body of b()})));
switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8];
}

@@ -122,14 +122,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
}

bb2: {
_4 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
_4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
}

bb3: {
StorageDead(_5);
PlaceMention(_4);
nop;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _4;
(((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}) = move _4;
goto -> bb4;
}

@@ -139,9 +139,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageLive(_10);
StorageLive(_11);
StorageLive(_12);
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
_12 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
_11 = &mut (*_12);
_10 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
_10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
}

bb5: {
@@ -157,7 +157,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
bb6: {
_13 = &mut (*_14);
StorageDead(_15);
_9 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
_9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
}

bb7: {
@@ -186,7 +186,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageDead(_4);
StorageDead(_19);
StorageDead(_20);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3;
discriminant((*(_1.0: &mut {async fn body of b()}))) = 3;
return;
}

@@ -199,7 +199,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageDead(_12);
StorageDead(_9);
StorageDead(_8);
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb12, unwind unreachable];
drop((((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()})) -> [return: bb12, unwind unreachable];
}

bb11: {
@@ -224,14 +224,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
}

bb14: {
_21 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
_21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
}

bb15: {
StorageDead(_22);
PlaceMention(_21);
nop;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _21;
(((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}) = move _21;
goto -> bb16;
}

@@ -241,9 +241,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageLive(_26);
StorageLive(_27);
StorageLive(_28);
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
_28 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()});
_27 = &mut (*_28);
_26 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
_26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
}

bb17: {
@@ -259,7 +259,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
bb18: {
_29 = &mut (*_30);
StorageDead(_31);
_25 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
_25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
}

bb19: {
@@ -283,7 +283,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageDead(_21);
StorageDead(_35);
StorageDead(_36);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4;
discriminant((*(_1.0: &mut {async fn body of b()}))) = 4;
return;
}

@@ -296,7 +296,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageDead(_28);
StorageDead(_25);
StorageDead(_24);
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb23, unwind unreachable];
drop((((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()})) -> [return: bb23, unwind unreachable];
}

bb22: {
@@ -319,7 +319,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,

bb25: {
_0 = Poll::<()>::Ready(move _37);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 1;
discriminant((*(_1.0: &mut {async fn body of b()}))) = 1;
return;
}

Original file line number Diff line number Diff line change
@@ -5,24 +5,24 @@
debug permit => (_1.0: ActionPermit<'_, T>);
debug ctx => (*(_1.1: &mut std::task::Context<'_>));
let mut _0: ();
let mut _2: {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
let mut _2: {async fn body of ActionPermit<'_, T>::perform()};
let mut _3: ActionPermit<'_, T>;
let mut _5: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
let mut _5: &mut {async fn body of ActionPermit<'_, T>::perform()};
let _6: ();
let mut _7: std::task::Poll<()>;
let mut _8: std::pin::Pin<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>;
let mut _8: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
let mut _9: &mut std::task::Context<'_>;
let mut _10: &mut std::task::Context<'_>;
scope 1 {
debug fut => _2;
let _4: std::pin::Pin<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>;
let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
scope 2 {
debug fut => _4;
scope 4 {
}
+ scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
+ debug _task_context => _31;
+ debug self => ((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})).0: ActionPermit<'_, T>);
+ debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>);
+ let _11: ActionPermit<'_, T>;
+ let mut _12: std::future::Ready<()>;
+ let mut _13: std::future::Ready<()>;
@@ -43,19 +43,19 @@
+ let mut _30: ();
+ let mut _31: &mut std::task::Context<'_>;
+ let mut _32: u32;
+ let mut _33: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _34: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _35: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _36: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _37: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _38: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _39: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _40: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _36: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _37: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ scope 8 {
+ debug self => (((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})) as variant#3).0: ActionPermit<'_, T>);
+ debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>);
+ let mut _15: std::future::Ready<()>;
+ scope 9 {
+ debug __awaitee => (((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})) as variant#3).1: std::future::Ready<()>);
+ debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>);
+ let _26: ();
+ scope 10 {
+ }
@@ -71,7 +71,7 @@
+ }
}
scope 3 {
+ scope 6 (inlined Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>::new_unchecked) {
+ scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
+ debug pointer => _5;
+ }
}
@@ -93,11 +93,11 @@
StorageLive(_4);
StorageLive(_5);
_5 = &mut _2;
- _4 = Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>::new_unchecked(move _5) -> [return: bb2, unwind unreachable];
- _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked(move _5) -> [return: bb2, unwind unreachable];
- }
-
- bb2: {
+ _4 = Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}> { __pointer: _5 };
+ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { __pointer: _5 };
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
@@ -106,7 +106,7 @@
StorageLive(_9);
_10 = deref_copy (_1.1: &mut std::task::Context<'_>);
_9 = &mut (*_10);
- _7 = <{async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6} as Future>::poll(move _8, move _9) -> [return: bb3, unwind unreachable];
- _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind unreachable];
+ StorageLive(_11);
+ StorageLive(_15);
+ StorageLive(_16);
@@ -123,7 +123,7 @@
+ StorageLive(_38);
+ StorageLive(_39);
+ StorageLive(_40);
+ _33 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _32 = discriminant((*_33));
+ switchInt(move _32) -> [0: bb3, 1: bb13, 3: bb12, otherwise: bb8];
}
@@ -164,8 +164,8 @@

+ bb3: {
+ _31 = move _9;
+ _34 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _35 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>);
+ StorageLive(_12);
+ StorageLive(_13);
@@ -183,7 +183,7 @@
- StorageDead(_2);
- return;
+ StorageDead(_13);
+ _36 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
+ goto -> bb5;
+ }
@@ -194,7 +194,7 @@
+ StorageLive(_19);
+ StorageLive(_20);
+ StorageLive(_21);
+ _37 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
+ _20 = &mut (*_21);
+ _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb6, unwind unreachable];
@@ -236,7 +236,7 @@
+ StorageDead(_12);
+ StorageDead(_28);
+ StorageDead(_29);
+ _38 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_38)) = 3;
+ goto -> bb2;
+ }
@@ -251,13 +251,13 @@
+ StorageDead(_18);
+ StorageDead(_17);
+ StorageDead(_12);
+ _39 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb11, unwind unreachable];
+ }
+
+ bb11: {
+ _7 = Poll::<()>::Ready(move _30);
+ _40 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_40)) = 1;
+ goto -> bb2;
+ }
Original file line number Diff line number Diff line change
@@ -5,24 +5,24 @@
debug permit => (_1.0: ActionPermit<'_, T>);
debug ctx => (*(_1.1: &mut std::task::Context<'_>));
let mut _0: ();
let mut _2: {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
let mut _2: {async fn body of ActionPermit<'_, T>::perform()};
let mut _3: ActionPermit<'_, T>;
let mut _5: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
let mut _5: &mut {async fn body of ActionPermit<'_, T>::perform()};
let _6: ();
let mut _7: std::task::Poll<()>;
let mut _8: std::pin::Pin<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>;
let mut _8: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
let mut _9: &mut std::task::Context<'_>;
let mut _10: &mut std::task::Context<'_>;
scope 1 {
debug fut => _2;
let _4: std::pin::Pin<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>;
let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
scope 2 {
debug fut => _4;
scope 4 {
}
+ scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
+ debug _task_context => _31;
+ debug self => ((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})).0: ActionPermit<'_, T>);
+ debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>);
+ let _11: ActionPermit<'_, T>;
+ let mut _12: std::future::Ready<()>;
+ let mut _13: std::future::Ready<()>;
@@ -43,21 +43,21 @@
+ let mut _30: ();
+ let mut _31: &mut std::task::Context<'_>;
+ let mut _32: u32;
+ let mut _33: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _34: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _35: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _36: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _37: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _38: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _39: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _40: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _41: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _42: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6};
+ let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _36: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _37: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _41: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ let mut _42: &mut {async fn body of ActionPermit<'_, T>::perform()};
+ scope 8 {
+ debug self => (((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})) as variant#3).0: ActionPermit<'_, T>);
+ debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>);
+ let mut _15: std::future::Ready<()>;
+ scope 9 {
+ debug __awaitee => (((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})) as variant#3).1: std::future::Ready<()>);
+ debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>);
+ let _26: ();
+ scope 10 {
+ }
@@ -73,7 +73,7 @@
+ }
}
scope 3 {
+ scope 6 (inlined Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>::new_unchecked) {
+ scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
+ debug pointer => _5;
+ }
}
@@ -95,11 +95,11 @@
StorageLive(_4);
StorageLive(_5);
_5 = &mut _2;
- _4 = Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>::new_unchecked(move _5) -> [return: bb2, unwind: bb5];
- _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked(move _5) -> [return: bb2, unwind: bb5];
- }
-
- bb2: {
+ _4 = Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}> { __pointer: _5 };
+ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { __pointer: _5 };
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
@@ -108,7 +108,7 @@
StorageLive(_9);
_10 = deref_copy (_1.1: &mut std::task::Context<'_>);
_9 = &mut (*_10);
- _7 = <{async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5];
- _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5];
+ StorageLive(_11);
+ StorageLive(_15);
+ StorageLive(_16);
@@ -127,7 +127,7 @@
+ StorageLive(_40);
+ StorageLive(_41);
+ StorageLive(_42);
+ _33 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _32 = discriminant((*_33));
+ switchInt(move _32) -> [0: bb5, 1: bb22, 2: bb21, 3: bb20, otherwise: bb10];
}
@@ -181,8 +181,8 @@
- return;
+ bb5: {
+ _31 = move _9;
+ _34 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _35 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>);
+ StorageLive(_12);
+ StorageLive(_13);
@@ -200,7 +200,7 @@
- drop(_2) -> [return: bb6, unwind terminate(cleanup)];
+ bb6: {
+ StorageDead(_13);
+ _36 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
+ goto -> bb7;
}
@@ -213,7 +213,7 @@
+ StorageLive(_19);
+ StorageLive(_20);
+ StorageLive(_21);
+ _37 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
+ _20 = &mut (*_21);
+ _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb8, unwind: bb15];
@@ -255,7 +255,7 @@
+ StorageDead(_12);
+ StorageDead(_28);
+ StorageDead(_29);
+ _38 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_38)) = 3;
+ goto -> bb4;
+ }
@@ -270,13 +270,13 @@
+ StorageDead(_18);
+ StorageDead(_17);
+ StorageDead(_12);
+ _39 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb13, unwind: bb19];
+ }
+
+ bb13: {
+ _7 = Poll::<()>::Ready(move _30);
+ _40 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_40)) = 1;
+ goto -> bb4;
+ }
@@ -308,12 +308,12 @@
+
+ bb18 (cleanup): {
+ StorageDead(_12);
+ _41 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb19, unwind terminate(cleanup)];
+ }
+
+ bb19 (cleanup): {
+ _42 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6});
+ _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
+ discriminant((*_42)) = 2;
+ goto -> bb2;
+ }
28 changes: 14 additions & 14 deletions tests/ui/async-await/future-sizes/async-awaiting-fut.stdout
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:21:21: 24:2}`: 3078 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of test()}`: 3078 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 0 bytes
print-type-size variant `Suspend0`: 3077 bytes
print-type-size local `.__awaitee`: 3077 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}
print-type-size local `.__awaitee`: 3077 bytes, type: {async fn body of calls_fut<{async fn body of big_fut()}>()}
print-type-size variant `Returned`: 0 bytes
print-type-size variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}>`: 3077 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size field `.value`: 3077 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}>`: 3077 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 3077 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 3077 bytes
print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}`: 3077 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of calls_fut<{async fn body of big_fut()}>()}`: 3077 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 1025 bytes
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
@@ -20,29 +20,29 @@ print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1
print-type-size padding: 1 bytes
print-type-size local `.fut`: 1025 bytes, alignment: 1 bytes
print-type-size local `..coroutine_field4`: 1 bytes, type: bool
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()}
print-type-size variant `Suspend1`: 3076 bytes
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
print-type-size padding: 1026 bytes
print-type-size local `..coroutine_field4`: 1 bytes, alignment: 1 bytes, type: bool
print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}
print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body of big_fut()}
print-type-size variant `Suspend2`: 2052 bytes
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
print-type-size padding: 1 bytes
print-type-size local `.fut`: 1025 bytes, alignment: 1 bytes
print-type-size local `..coroutine_field4`: 1 bytes, type: bool
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()}
print-type-size variant `Returned`: 1025 bytes
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
print-type-size variant `Panicked`: 1025 bytes
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}>`: 1025 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size field `.value`: 1025 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}>`: 1025 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1025 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 1025 bytes
print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}`: 1025 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of big_fut()}`: 1025 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 1024 bytes
print-type-size upvar `.arg`: 1024 bytes
@@ -52,13 +52,13 @@ print-type-size variant `Panicked`: 1024 bytes
print-type-size upvar `.arg`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 bytes
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 1 bytes
@@ -67,7 +67,7 @@ print-type-size discriminant: 1 bytes
print-type-size variant `Ready`: 0 bytes
print-type-size field `.0`: 0 bytes
print-type-size variant `Pending`: 0 bytes
print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}`: 1 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of wait()}`: 1 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 0 bytes
print-type-size variant `Returned`: 0 bytes
26 changes: 13 additions & 13 deletions tests/ui/async-await/future-sizes/large-arg.stdout
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
print-type-size type: `{async fn body@$DIR/large-arg.rs:6:21: 8:2}`: 3076 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of test()}`: 3076 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 0 bytes
print-type-size variant `Suspend0`: 3075 bytes
print-type-size local `.__awaitee`: 3075 bytes, type: {async fn body@$DIR/large-arg.rs:10:30: 12:2}
print-type-size local `.__awaitee`: 3075 bytes, type: {async fn body of a<[u8; 1024]>()}
print-type-size variant `Returned`: 0 bytes
print-type-size variant `Panicked`: 0 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:10:30: 12:2}>`: 3075 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size field `.value`: 3075 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/large-arg.rs:10:30: 12:2}>`: 3075 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 3075 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 3075 bytes
print-type-size type: `{async fn body@$DIR/large-arg.rs:10:30: 12:2}`: 3075 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of a<[u8; 1024]>()}`: 3075 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size variant `Suspend0`: 3074 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size local `.__awaitee`: 2050 bytes, type: {async fn body@$DIR/large-arg.rs:13:26: 15:2}
print-type-size local `.__awaitee`: 2050 bytes, type: {async fn body of b<[u8; 1024]>()}
print-type-size variant `Returned`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size variant `Panicked`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:13:26: 15:2}>`: 2050 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size field `.value`: 2050 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/large-arg.rs:13:26: 15:2}>`: 2050 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 2050 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 2050 bytes
print-type-size type: `{async fn body@$DIR/large-arg.rs:13:26: 15:2}`: 2050 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of b<[u8; 1024]>()}`: 2050 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size variant `Suspend0`: 2049 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body@$DIR/large-arg.rs:16:26: 18:2}
print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body of c<[u8; 1024]>()}
print-type-size variant `Returned`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size variant `Panicked`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:16:26: 18:2}>`: 1025 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size field `.value`: 1025 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/large-arg.rs:16:26: 18:2}>`: 1025 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1025 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 1025 bytes
@@ -50,7 +50,7 @@ print-type-size discriminant: 1 bytes
print-type-size variant `Ready`: 1024 bytes
print-type-size field `.0`: 1024 bytes
print-type-size variant `Pending`: 0 bytes
print-type-size type: `{async fn body@$DIR/large-arg.rs:16:26: 18:2}`: 1025 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of c<[u8; 1024]>()}`: 1025 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 1024 bytes
print-type-size upvar `.t`: 1024 bytes
13 changes: 12 additions & 1 deletion tests/ui/consts/auxiliary/issue-63226.rs
Original file line number Diff line number Diff line change
@@ -2,13 +2,24 @@ pub struct VTable{
state:extern "C" fn(),
}

impl VTable{
impl VTable {
pub const fn vtable()->&'static VTable{
Self::VTABLE
}

const VTABLE: &'static VTable =
&VTable{state};

pub const VTABLE2: &'static VTable =
&VTable{state: state2};
}

pub const VTABLE3: &'static VTable =
&VTable{state: state3};

// Only referenced via a `pub const fn`, and yet reachable.
extern "C" fn state() {}
// Only referenced via a associated `pub const`, and yet reachable.
extern "C" fn state2() {}
// Only referenced via a free `pub const`, and yet reachable.
extern "C" fn state3() {}
2 changes: 2 additions & 0 deletions tests/ui/consts/issue-63226.rs
Original file line number Diff line number Diff line change
@@ -8,5 +8,7 @@
use issue_63226::VTable;

static ICE_ICE:&'static VTable=VTable::vtable();
static MORE_ICE:&'static VTable=VTable::VTABLE2;
static MORE_ICE3:&'static VTable=issue_63226::VTABLE3;

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/debuginfo/auxiliary/dylib-dep-helper-aux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: -g -Cstrip=none

#[inline(never)]
pub fn callback<F>(f: F)
where
F: FnOnce((&'static str, u32)),
{
f((file!(), line!()))
}

#[inline(always)]
pub fn callback_inlined<F>(f: F)
where
F: FnOnce((&'static str, u32)),
{
f((file!(), line!()))
}
19 changes: 19 additions & 0 deletions tests/ui/debuginfo/auxiliary/dylib-dep-helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ compile-flags: -g -Cstrip=none

#![crate_type = "cdylib"]
#![crate_type = "rlib"]

#![allow(improper_ctypes_definitions)]

type Pos = (&'static str, u32);

macro_rules! pos {
() => {
(file!(), line!())
};
}

#[no_mangle]
pub extern "C" fn foo(outer: Pos, inner: fn(Pos, Pos)) {
inner(outer, pos!());
}
115 changes: 115 additions & 0 deletions tests/ui/debuginfo/backtrace-dylib-dep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Check that backtrace info is correctly generated for dynamic libraries and is usable by a
// rust binary.
// Part of porting some backtrace tests to rustc: <https://github.com/rust-lang/rust/issues/122899>.
// Original test:
// <https://github.com/rust-lang/backtrace-rs/tree/6fa4b85b9962c3e1be8c2e5cc605cd078134152b/crates/dylib-dep>
// ignore-tidy-linelength
//@ ignore-android FIXME #17520
//@ ignore-fuchsia Backtraces not symbolized
//@ needs-unwind
//@ compile-flags: -g -Copt-level=0 -Cstrip=none
//@ aux-crate: dylib_dep_helper=dylib-dep-helper.rs
//@ aux-crate: auxiliary=dylib-dep-helper-aux.rs
//@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written).
//@ run-pass

#![allow(improper_ctypes)]
#![allow(improper_ctypes_definitions)]

extern crate dylib_dep_helper;
extern crate auxiliary;

use std::backtrace::Backtrace;

macro_rules! pos {
() => {
(file!(), line!())
};
}

macro_rules! check {
($($pos:expr),*) => ({
verify(&[$($pos,)* pos!()]);
})
}

fn verify(filelines: &[Pos]) {
let trace = Backtrace::capture();
eprintln!("-----------------------------------");
eprintln!("looking for:");
for (file, line) in filelines.iter().rev() {
eprintln!("\t{file}:{line}");
}
eprintln!("found:\n{trace:#?}");
let mut iter = filelines.iter().rev();
// FIXME(jieyouxu): use proper `BacktraceFrame` accessors when it becomes available. Right now,
// this depends on the debug format of `Backtrace` which is of course fragile.
let backtrace = format!("{:#?}", trace);
while let Some((file, line)) = iter.next() {
// FIXME(jieyouxu): make this test use proper accessors on `BacktraceFrames` once it has
// them.
assert!(backtrace.contains(file), "expected backtrace to contain {}", file);
assert!(backtrace.contains(&line.to_string()), "expected backtrace to contain {}", line);
}
}

type Pos = (&'static str, u32);

extern "C" {
#[link_name = "foo"]
fn foo(p: Pos, cb: fn(Pos, Pos));
}

fn main() {
std::env::set_var("RUST_BACKTRACE", "1");
std::env::set_var("WASMTIME_BACKTRACE_DETAILS", "1");

unsafe {
foo(pos!(), |a, b| {
check!(a, b)
})
}

outer(pos!());
}

#[inline(never)]
fn outer(main_pos: Pos) {
inner(main_pos, pos!());
inner_inlined(main_pos, pos!());
}

#[inline(never)]
fn inner(main_pos: Pos, outer_pos: Pos) {
check!(main_pos, outer_pos);
check!(main_pos, outer_pos);
let inner_pos = pos!(); auxiliary::callback(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
let inner_pos = pos!(); auxiliary::callback_inlined(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
}

#[inline(always)]
fn inner_inlined(main_pos: Pos, outer_pos: Pos) {
check!(main_pos, outer_pos);
check!(main_pos, outer_pos);

#[inline(always)]
fn inner_further_inlined(main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
check!(main_pos, outer_pos, inner_pos);
}
inner_further_inlined(main_pos, outer_pos, pos!());

let inner_pos = pos!(); auxiliary::callback(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
let inner_pos = pos!(); auxiliary::callback_inlined(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});

// this tests a distinction between two independent calls to the inlined function.
// (un)fortunately, LLVM somehow merges two consecutive such calls into one node.
inner_further_inlined(main_pos, outer_pos, pos!());
}
2 changes: 1 addition & 1 deletion tests/ui/higher-ranked/trait-bounds/future.current.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
error: the compiler unexpectedly panicked. this is a bug.

query stack during panic:
#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> {async fn body@$DIR/future.rs:33:35: 35:2}: core::future::future::Future`
#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> {async fn body of strlen()}: core::future::future::Future`
#1 [codegen_select_candidate] computing candidate for `<strlen as Trait>`
end of query stack
78 changes: 78 additions & 0 deletions tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// ICE: failed to get layout for [type error]
// issue: rust-lang/rust#92979

use std::fs;
use std::fs::File;
use std::io::Read;
use std::convert::TryInto;

fn get_file_as_byte_vec(filename: &String) -> Vec<u8> {
let mut f = File::open(&filename).expect("no file found");
let metadata = fs::metadata(&filename).expect("unable to read metadata");
let mut buffer = vec![0; metadata.len() as usize];
f.read(&mut buffer).expect("buffer overflow");

buffer
}



fn demo<T, const N: usize>(v: Vec<T>) -> [T; N] {
v.try_into()
.unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
}


fn main() {

// Specify filepath
let file: &String = &String::from("SomeBinaryDataFileWith4ByteHeaders_f32s_and_u32s");

// Read file into a vector of bytes
let file_data = get_file_as_byte_vec(file);

// Print length of vector and first few values
let length = file_data.len();
println!("The read function read {} bytes", length);
println!("The first few bytes:");
for i in 0..20{
println!("{}", file_data[i]);
}

// Manually count just to make sure
let mut n: u64 = 0;
for data in file_data{
n += 1;
}
println!("We counted {} bytes", n);
assert!(n as usize == length, "Manual counting does not equal len method");

// Simulation parameters
const N: usize = 49627502; // Number of Particles
const bs: f64 = 125.0; // Box Size
const HEADER_INCREMENT: u64 = 4*1;

// Initialize index and counter variables
let (mut j, mut pos, mut vel, mut id, mut mass): (u64, u64, u64, u64, u64) = (0, 0, 0, 0, 0);

// Unpack Position Data
j += HEADER_INCREMENT;
let mut position: Vec<f32> = Vec::new();
while position.len() < N*3 {

let p: Vec<u8> = Vec::new();
for item in 0i8..4 {
let item = item;
p.push(file_data[j as usize]);
j += 1;
}
&mut position[position.len()] = f32::from_be_bytes(demo(p));
//~^ ERROR invalid left-hand side of assignment
}

// Ensure position data is indeed position by checking values
for p in position {
assert!((p > 0.) & (p < 125.), "Not in box")
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0070]: invalid left-hand side of assignment
--> $DIR/failed-to-get-layout-for-type-error-ice-92979.rs:69:39
|
LL | &mut position[position.len()] = f32::from_be_bytes(demo(p));
| ----------------------------- ^
| |
| cannot assign to this expression
|
help: consider dereferencing here to assign to the mutably borrowed value
|
LL | *&mut position[position.len()] = f32::from_be_bytes(demo(p));
| +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0070`.
59 changes: 59 additions & 0 deletions tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// ICE argument to function with "rust-call" ABI is not a tuple
// issue: rust-lang/rust#81974

#![feature(unboxed_closures)]
#![feature(fn_traits)]

use std::collections::HashMap;
use std::hash::Hash;

struct CachedFun<A, B> {
cache: HashMap<A, B>,
fun: fn(&mut CachedFun<A, B>, A) -> B,
}

impl<A: Eq + Hash, B> CachedFun<A, B> {
fn new(fun: fn(&mut Self, A) -> B) -> Self {
CachedFun {
cache: HashMap::new(),
fun,
}
}
}

impl<A, B> FnOnce<A> for CachedFun<A, B>
//~^ ERROR type parameter to bare `FnOnce` trait must be a tuple
where
A: Eq + Hash + Clone,
B: Clone,
{
type Output = B;
extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
self.call_mut(a)
//~^ ERROR `A` is not a tuple
}
}

impl<A, B> FnMut<A> for CachedFun<A, B>
//~^ ERROR type parameter to bare `FnMut` trait must be a tuple
where
A: Eq + Hash + Clone,
B: Clone,
{
extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
self.cache.get(&a).map(|a| a.clone()).unwrap_or_else(|| {
let b = (self.fun)(self, a.clone());
self.cache.insert(a, b.clone());
b
})
}
}

fn main() -> () {
let pesce = |y: &mut CachedFun<i32, i32>, x| x + 1;
let cachedcoso = CachedFun::new(pesce);
cachedcoso.call_once(1);
//~^ ERROR `i32` is not a tuple
}
78 changes: 78 additions & 0 deletions tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:24:12
|
LL | impl<A, B> FnOnce<A> for CachedFun<A, B>
| ^^^^^^^^^ the trait `Tuple` is not implemented for `A`
|
note: required by a bound in `FnOnce`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
help: consider further restricting this bound
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++

error[E0059]: type parameter to bare `FnMut` trait must be a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:38:12
|
LL | impl<A, B> FnMut<A> for CachedFun<A, B>
| ^^^^^^^^ the trait `Tuple` is not implemented for `A`
|
note: required by a bound in `FnMut`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
help: consider further restricting this bound
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++

error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
|
LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
|
help: consider further restricting this bound
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++

error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:44:5
|
LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
|
help: consider further restricting this bound
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++

error[E0277]: `A` is not a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:33:23
|
LL | self.call_mut(a)
| -------- ^ the trait `Tuple` is not implemented for `A`
| |
| required by a bound introduced by this call
|
note: required by a bound in `call_mut`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
help: consider further restricting this bound
|
LL | A: Eq + Hash + Clone + std::marker::Tuple,
| ++++++++++++++++++++

error[E0277]: `i32` is not a tuple
--> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:57:26
|
LL | cachedcoso.call_once(1);
| --------- ^ the trait `Tuple` is not implemented for `i32`
| |
| required by a bound introduced by this call
|
note: required by a bound in `call_once`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0059, E0277.
For more information about an error, try `rustc --explain E0059`.
10 changes: 5 additions & 5 deletions tests/ui/print_type_sizes/async.stdout
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
print-type-size type: `{async fn body@$DIR/async.rs:10:36: 13:2}`: 16386 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of test()}`: 16386 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 8192 bytes
print-type-size upvar `.arg`: 8192 bytes
print-type-size variant `Suspend0`: 16385 bytes
print-type-size upvar `.arg`: 8192 bytes
print-type-size local `.arg`: 8192 bytes
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async.rs:8:17: 8:19}
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()}
print-type-size variant `Returned`: 8192 bytes
print-type-size upvar `.arg`: 8192 bytes
print-type-size variant `Panicked`: 8192 bytes
@@ -16,9 +16,9 @@ print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment
print-type-size variant `MaybeUninit`: 8192 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 8192 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async.rs:8:17: 8:19}>`: 1 bytes, alignment: 1 bytes
print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size field `.value`: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async.rs:8:17: 8:19}>`: 1 bytes, alignment: 1 bytes
print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes
print-type-size variant `MaybeUninit`: 1 bytes
print-type-size field `.uninit`: 0 bytes
print-type-size field `.value`: 1 bytes
@@ -27,7 +27,7 @@ print-type-size discriminant: 1 bytes
print-type-size variant `Ready`: 0 bytes
print-type-size field `.0`: 0 bytes
print-type-size variant `Pending`: 0 bytes
print-type-size type: `{async fn body@$DIR/async.rs:8:17: 8:19}`: 1 bytes, alignment: 1 bytes
print-type-size type: `{async fn body of wait()}`: 1 bytes, alignment: 1 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `Unresumed`: 0 bytes
print-type-size variant `Returned`: 0 bytes
38 changes: 38 additions & 0 deletions tests/ui/traits/trait-selection-ice-84727.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// ICE Where clause `Binder(..)` was applicable to `Obligation(..)` but now is not
// issue: rust-lang/rust#84727

struct Cell<Fg, Bg = Fg> {
foreground: Color<Fg>,
//~^ ERROR cannot find type `Color` in this scope
background: Color<Bg>,
//~^ ERROR cannot find type `Color` in this scope
}

trait Over<Bottom, Output> {
fn over(self) -> Output;
}

impl<TopFg, TopBg, BottomFg, BottomBg, NewFg, NewBg>
Over<Cell<BottomFg, BottomBg>, Cell<NewFg, NewBg>> for Cell<TopFg, TopBg>
where
Self: Over<Color<BottomBg>, Cell<NewFg>>,
//~^ ERROR cannot find type `Color` in this scope
{
fn over(self) -> Cell<NewFg> {
//~^ ERROR mismatched types
self.over();
}
}

impl<'b, TopFg, TopBg, BottomFg, BottomBg> Over<&Cell<BottomFg, BottomBg>, ()>
for Cell<TopFg, TopBg>
where
Cell<TopFg, TopBg>: Over<Cell<BottomFg>, Cell<BottomFg>>,
{
fn over(self) -> Cell<NewBg> {
//~^ ERROR cannot find type `NewBg` in this scope
self.over();
}
}

pub fn main() {}
47 changes: 47 additions & 0 deletions tests/ui/traits/trait-selection-ice-84727.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
error[E0412]: cannot find type `Color` in this scope
--> $DIR/trait-selection-ice-84727.rs:5:17
|
LL | foreground: Color<Fg>,
| ^^^^^ not found in this scope

error[E0412]: cannot find type `Color` in this scope
--> $DIR/trait-selection-ice-84727.rs:7:17
|
LL | background: Color<Bg>,
| ^^^^^ not found in this scope

error[E0412]: cannot find type `Color` in this scope
--> $DIR/trait-selection-ice-84727.rs:18:16
|
LL | Self: Over<Color<BottomBg>, Cell<NewFg>>,
| ^^^^^ not found in this scope

error[E0412]: cannot find type `NewBg` in this scope
--> $DIR/trait-selection-ice-84727.rs:32:27
|
LL | fn over(self) -> Cell<NewBg> {
| ^^^^^ not found in this scope
|
help: you might be missing a type parameter
|
LL | impl<'b, TopFg, TopBg, BottomFg, BottomBg, NewBg> Over<&Cell<BottomFg, BottomBg>, ()>
| +++++++

error[E0308]: mismatched types
--> $DIR/trait-selection-ice-84727.rs:21:22
|
LL | fn over(self) -> Cell<NewFg> {
| ---- ^^^^^^^^^^^ expected `Cell<NewFg>`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
LL |
LL | self.over();
| - help: remove this semicolon to return this value
|
= note: expected struct `Cell<NewFg>`
found unit type `()`

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0308, E0412.
For more information about an error, try `rustc --explain E0308`.
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ error: concrete type differs from previous defining opaque type use
--> $DIR/hkl_forbidden4.rs:13:1
|
LL | async fn operation(_: &mut ()) -> () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body@$DIR/hkl_forbidden4.rs:13:38: 16:2}`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}`
|
note: previous use here
--> $DIR/hkl_forbidden4.rs:15:5
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ check-pass

#![feature(type_alias_impl_trait)]
#![allow(dead_code)]

trait Duh {}

impl Duh for i32 {}

trait Trait {
type Assoc: Duh;
}

impl<R: Duh, F: FnMut() -> R> Trait for F {
type Assoc = R;
}

type Sendable = impl Send + Duh;

type Foo = impl Trait<Assoc = Sendable>;

fn foo() -> Foo {
|| 42
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//@ check-pass

// See https://doc.rust-lang.org/1.77.0/nightly-rustc/rustc_lint/opaque_hidden_inferred_bound/static.OPAQUE_HIDDEN_INFERRED_BOUND.html#example

#![feature(type_alias_impl_trait)]
#![allow(dead_code)]

trait Duh {}

impl Duh for i32 {}

trait Trait {
type Assoc: Duh;
}

impl<R: Duh, F: FnMut() -> R> Trait for F {
type Assoc = R;
}

type Sendable = impl Send;

type Foo = impl Trait<Assoc = Sendable>;
//~^ WARNING opaque type `Foo` does not satisfy its associated type bounds

fn foo() -> Foo {
|| 42
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
warning: opaque type `Foo` does not satisfy its associated type bounds
--> $DIR/tait-in-function-return-type-issue-101903.rs:22:23
|
LL | type Assoc: Duh;
| --- this associated type bound is unsatisfied for `Sendable`
...
LL | type Foo = impl Trait<Assoc = Sendable>;
| ^^^^^^^^^^^^^^^^
|
= note: `#[warn(opaque_hidden_inferred_bound)]` on by default

warning: 1 warning emitted