Skip to content

Commit cd10d85

Browse files
matthiaskrgrRenjiSann
authored andcommitted
Rollup merge of rust-lang#122922 - kpreid:print-async, r=compiler-errors
-Zprint-type-sizes: print the types of awaitees and unnamed coroutine locals. This should assist comprehending the size of coroutines. In particular, whenever a future is suspended while awaiting another future, the latter is given the special name `__awaitee`, and now the type of the awaited future will be printed, allowing identifying caller/callee — er, I mean, poller/pollee — relationships. It would be possible to include the type name in more cases, but I thought that that might be overly verbose (`print-type-sizes` is already a lot of text) and ordinary named fields or variables are easier for readers to discover the types of. This change will also synergize with my other PR rust-lang#122923 which changes type printing to print the path of the `async fn` instead of the span. Implementation note: I'm not sure if `Symbol::intern` is appropriate for this application, but it was the obvious way to not have to remove the `Copy` implementation from `FieldInfo`, or add a `'tcx` lifetime, while avoiding keeping a lot of possibly redundant strings in memory. I don't know what the proper tradeoff to make here is (though presumably it is not too important for a `-Z` debugging option).
2 parents 5f8e9d0 + 44d185b commit cd10d85

File tree

5 files changed

+34
-16
lines changed

5 files changed

+34
-16
lines changed

compiler/rustc_session/src/code_stats.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pub struct FieldInfo {
4444
pub offset: u64,
4545
pub size: u64,
4646
pub align: u64,
47+
/// Name of the type of this field.
48+
/// Present only if the creator thought that this would be important for identifying the field,
49+
/// typically because the field name is uninformative.
50+
pub type_name: Option<Symbol>,
4751
}
4852

4953
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -192,7 +196,7 @@ impl CodeStats {
192196
fields.sort_by_key(|f| (f.offset, f.size));
193197

194198
for field in fields {
195-
let FieldInfo { kind, ref name, offset, size, align } = field;
199+
let FieldInfo { kind, ref name, offset, size, align, type_name } = field;
196200

197201
if offset > min_offset {
198202
let pad = offset - min_offset;
@@ -201,21 +205,27 @@ impl CodeStats {
201205

202206
if offset < min_offset {
203207
// If this happens it's probably a union.
204-
println!(
208+
print!(
205209
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \
206210
offset: {offset} bytes, \
207211
alignment: {align} bytes"
208212
);
209213
} else if info.packed || offset == min_offset {
210-
println!("print-type-size {indent}{kind} `.{name}`: {size} bytes");
214+
print!("print-type-size {indent}{kind} `.{name}`: {size} bytes");
211215
} else {
212216
// Include field alignment in output only if it caused padding injection
213-
println!(
217+
print!(
214218
"print-type-size {indent}{kind} `.{name}`: {size} bytes, \
215219
alignment: {align} bytes"
216220
);
217221
}
218222

223+
if let Some(type_name) = type_name {
224+
println!(", type: {type_name}");
225+
} else {
226+
println!();
227+
}
228+
219229
min_offset = offset + size;
220230
}
221231
}

compiler/rustc_ty_utils/src/layout.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_middle::ty::layout::{
1010
use rustc_middle::ty::print::with_no_trimmed_paths;
1111
use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
1212
use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
13+
use rustc_span::sym;
1314
use rustc_span::symbol::Symbol;
1415
use rustc_target::abi::*;
1516

@@ -1007,6 +1008,7 @@ fn variant_info_for_adt<'tcx>(
10071008
offset: offset.bytes(),
10081009
size: field_layout.size.bytes(),
10091010
align: field_layout.align.abi.bytes(),
1011+
type_name: None,
10101012
}
10111013
})
10121014
.collect();
@@ -1090,6 +1092,7 @@ fn variant_info_for_coroutine<'tcx>(
10901092
offset: offset.bytes(),
10911093
size: field_layout.size.bytes(),
10921094
align: field_layout.align.abi.bytes(),
1095+
type_name: None,
10931096
}
10941097
})
10951098
.collect();
@@ -1104,19 +1107,24 @@ fn variant_info_for_coroutine<'tcx>(
11041107
.iter()
11051108
.enumerate()
11061109
.map(|(field_idx, local)| {
1110+
let field_name = coroutine.field_names[*local];
11071111
let field_layout = variant_layout.field(cx, field_idx);
11081112
let offset = variant_layout.fields.offset(field_idx);
11091113
// The struct is as large as the last field's end
11101114
variant_size = variant_size.max(offset + field_layout.size);
11111115
FieldInfo {
11121116
kind: FieldKind::CoroutineLocal,
1113-
name: coroutine.field_names[*local].unwrap_or(Symbol::intern(&format!(
1117+
name: field_name.unwrap_or(Symbol::intern(&format!(
11141118
".coroutine_field{}",
11151119
local.as_usize()
11161120
))),
11171121
offset: offset.bytes(),
11181122
size: field_layout.size.bytes(),
11191123
align: field_layout.align.abi.bytes(),
1124+
// Include the type name if there is no field name, or if the name is the
1125+
// __awaitee placeholder symbol which means a child future being `.await`ed.
1126+
type_name: (field_name.is_none() || field_name == Some(sym::__awaitee))
1127+
.then(|| Symbol::intern(&field_layout.ty.to_string())),
11201128
}
11211129
})
11221130
.chain(upvar_fields.iter().copied())

tests/ui/async-await/future-sizes/async-awaiting-fut.stdout

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:21:21: 24:2}`:
22
print-type-size discriminant: 1 bytes
33
print-type-size variant `Unresumed`: 0 bytes
44
print-type-size variant `Suspend0`: 3077 bytes
5-
print-type-size local `.__awaitee`: 3077 bytes
5+
print-type-size local `.__awaitee`: 3077 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}
66
print-type-size variant `Returned`: 0 bytes
77
print-type-size variant `Panicked`: 0 bytes
88
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}>`: 3077 bytes, alignment: 1 bytes
@@ -19,19 +19,19 @@ print-type-size variant `Suspend0`: 2052 bytes
1919
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
2020
print-type-size padding: 1 bytes
2121
print-type-size local `.fut`: 1025 bytes, alignment: 1 bytes
22-
print-type-size local `..coroutine_field4`: 1 bytes
23-
print-type-size local `.__awaitee`: 1 bytes
22+
print-type-size local `..coroutine_field4`: 1 bytes, type: bool
23+
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}
2424
print-type-size variant `Suspend1`: 3076 bytes
2525
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
2626
print-type-size padding: 1026 bytes
27-
print-type-size local `..coroutine_field4`: 1 bytes, alignment: 1 bytes
28-
print-type-size local `.__awaitee`: 1025 bytes
27+
print-type-size local `..coroutine_field4`: 1 bytes, alignment: 1 bytes, type: bool
28+
print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}
2929
print-type-size variant `Suspend2`: 2052 bytes
3030
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
3131
print-type-size padding: 1 bytes
3232
print-type-size local `.fut`: 1025 bytes, alignment: 1 bytes
33-
print-type-size local `..coroutine_field4`: 1 bytes
34-
print-type-size local `.__awaitee`: 1 bytes
33+
print-type-size local `..coroutine_field4`: 1 bytes, type: bool
34+
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}
3535
print-type-size variant `Returned`: 1025 bytes
3636
print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
3737
print-type-size variant `Panicked`: 1025 bytes

tests/ui/async-await/future-sizes/large-arg.stdout

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ print-type-size type: `{async fn body@$DIR/large-arg.rs:6:21: 8:2}`: 3076 bytes,
22
print-type-size discriminant: 1 bytes
33
print-type-size variant `Unresumed`: 0 bytes
44
print-type-size variant `Suspend0`: 3075 bytes
5-
print-type-size local `.__awaitee`: 3075 bytes
5+
print-type-size local `.__awaitee`: 3075 bytes, type: {async fn body@$DIR/large-arg.rs:10:30: 12:2}
66
print-type-size variant `Returned`: 0 bytes
77
print-type-size variant `Panicked`: 0 bytes
88
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:10:30: 12:2}>`: 3075 bytes, alignment: 1 bytes
@@ -17,7 +17,7 @@ print-type-size variant `Unresumed`: 1024 bytes
1717
print-type-size upvar `.t`: 1024 bytes
1818
print-type-size variant `Suspend0`: 3074 bytes
1919
print-type-size upvar `.t`: 1024 bytes
20-
print-type-size local `.__awaitee`: 2050 bytes
20+
print-type-size local `.__awaitee`: 2050 bytes, type: {async fn body@$DIR/large-arg.rs:13:26: 15:2}
2121
print-type-size variant `Returned`: 1024 bytes
2222
print-type-size upvar `.t`: 1024 bytes
2323
print-type-size variant `Panicked`: 1024 bytes
@@ -34,7 +34,7 @@ print-type-size variant `Unresumed`: 1024 bytes
3434
print-type-size upvar `.t`: 1024 bytes
3535
print-type-size variant `Suspend0`: 2049 bytes
3636
print-type-size upvar `.t`: 1024 bytes
37-
print-type-size local `.__awaitee`: 1025 bytes
37+
print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body@$DIR/large-arg.rs:16:26: 18:2}
3838
print-type-size variant `Returned`: 1024 bytes
3939
print-type-size upvar `.t`: 1024 bytes
4040
print-type-size variant `Panicked`: 1024 bytes

tests/ui/print_type_sizes/async.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ print-type-size upvar `.arg`: 8192 bytes
55
print-type-size variant `Suspend0`: 16385 bytes
66
print-type-size upvar `.arg`: 8192 bytes
77
print-type-size local `.arg`: 8192 bytes
8-
print-type-size local `.__awaitee`: 1 bytes
8+
print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async.rs:8:17: 8:19}
99
print-type-size variant `Returned`: 8192 bytes
1010
print-type-size upvar `.arg`: 8192 bytes
1111
print-type-size variant `Panicked`: 8192 bytes

0 commit comments

Comments
 (0)