Skip to content

Commit 75703c1

Browse files
committed
Auto merge of rust-lang#133287 - matthiaskrgr:rollup-ab9j3pu, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#130236 (unstable feature usage metrics) - rust-lang#131544 (Make asm label blocks safe context) - rust-lang#131586 (Support s390x z13 vector ABI) - rust-lang#132489 (Fix closure arg extraction in `extract_callable_info`, generalize it to async closures) - rust-lang#133078 (tests: ui/inline-consts: add issue number to a test, rename other tests) - rust-lang#133283 (Don't exclude relnotes from `needs-triage` label) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 717f5df + df2413c commit 75703c1

40 files changed

+1287
-170
lines changed

Diff for: Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -3685,6 +3685,8 @@ version = "0.0.0"
36853685
dependencies = [
36863686
"rustc_data_structures",
36873687
"rustc_span",
3688+
"serde",
3689+
"serde_json",
36883690
]
36893691

36903692
[[package]]

Diff for: compiler/rustc_abi/src/layout/ty.rs

+18
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,24 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
209209
}
210210
}
211211

212+
pub fn is_single_vector_element<C>(self, cx: &C, expected_size: Size) -> bool
213+
where
214+
Ty: TyAbiInterface<'a, C>,
215+
C: HasDataLayout,
216+
{
217+
match self.backend_repr {
218+
BackendRepr::Vector { .. } => self.size == expected_size,
219+
BackendRepr::Memory { .. } => {
220+
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
221+
self.field(cx, 0).is_single_vector_element(cx, expected_size)
222+
} else {
223+
false
224+
}
225+
}
226+
_ => false,
227+
}
228+
}
229+
212230
pub fn is_adt<C>(self) -> bool
213231
where
214232
Ty: TyAbiInterface<'a, C>,

Diff for: compiler/rustc_driver_impl/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ driver_impl_rlink_rustc_version_mismatch = .rlink file was produced by rustc ver
2323
driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}`
2424
2525
driver_impl_rlink_wrong_file_type = The input does not look like a .rlink file
26+
27+
driver_impl_unstable_feature_usage = cannot dump feature usage metrics: {$error}

Diff for: compiler/rustc_driver_impl/src/lib.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use rustc_interface::{Linker, Queries, interface, passes};
5151
use rustc_lint::unerased_lint_store;
5252
use rustc_metadata::creader::MetadataLoader;
5353
use rustc_metadata::locator;
54+
use rustc_middle::ty::TyCtxt;
5455
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
5556
use rustc_session::config::{
5657
CG_OPTIONS, ErrorOutputType, Input, OutFileName, OutputType, UnstableOptions, Z_OPTIONS,
@@ -103,7 +104,7 @@ mod signal_handler {
103104

104105
use crate::session_diagnostics::{
105106
RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
106-
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead,
107+
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage,
107108
};
108109

109110
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
@@ -431,6 +432,10 @@ fn run_compiler(
431432
// Make sure name resolution and macro expansion is run.
432433
queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering());
433434

435+
if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
436+
queries.global_ctxt()?.enter(|tcxt| dump_feature_usage_metrics(tcxt, metrics_dir));
437+
}
438+
434439
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
435440
return early_exit();
436441
}
@@ -475,6 +480,23 @@ fn run_compiler(
475480
})
476481
}
477482

483+
fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &PathBuf) {
484+
let output_filenames = tcxt.output_filenames(());
485+
let mut metrics_file_name = std::ffi::OsString::from("unstable_feature_usage_metrics-");
486+
let mut metrics_path = output_filenames.with_directory_and_extension(metrics_dir, "json");
487+
let metrics_file_stem =
488+
metrics_path.file_name().expect("there should be a valid default output filename");
489+
metrics_file_name.push(metrics_file_stem);
490+
metrics_path.pop();
491+
metrics_path.push(metrics_file_name);
492+
if let Err(error) = tcxt.features().dump_feature_usage_metrics(metrics_path) {
493+
// FIXME(yaahc): once metrics can be enabled by default we will want "failure to emit
494+
// default metrics" to only produce a warning when metrics are enabled by default and emit
495+
// an error only when the user manually enables metrics
496+
tcxt.dcx().emit_err(UnstableFeatureUsage { error });
497+
}
498+
}
499+
478500
// Extract output directory and file from matches.
479501
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileName>) {
480502
let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));

Diff for: compiler/rustc_driver_impl/src/session_diagnostics.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::error::Error;
2+
13
use rustc_macros::{Diagnostic, Subdiagnostic};
24

35
#[derive(Diagnostic)]
@@ -93,3 +95,9 @@ pub(crate) struct IceFlags {
9395
#[derive(Diagnostic)]
9496
#[diag(driver_impl_ice_exclude_cargo_defaults)]
9597
pub(crate) struct IceExcludeCargoDefaults;
98+
99+
#[derive(Diagnostic)]
100+
#[diag(driver_impl_unstable_feature_usage)]
101+
pub(crate) struct UnstableFeatureUsage {
102+
pub error: Box<dyn Error>,
103+
}

Diff for: compiler/rustc_feature/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ edition = "2021"
77
# tidy-alphabetical-start
88
rustc_data_structures = { path = "../rustc_data_structures" }
99
rustc_span = { path = "../rustc_span" }
10+
serde = { version = "1.0.125", features = [ "derive" ] }
11+
serde_json = "1.0.59"
1012
# tidy-alphabetical-end

Diff for: compiler/rustc_feature/src/unstable.rs

+50
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! List of the unstable feature gates.
22
3+
use std::path::PathBuf;
4+
35
use rustc_data_structures::fx::FxHashSet;
46
use rustc_span::Span;
57
use rustc_span::symbol::{Symbol, sym};
@@ -651,6 +653,54 @@ declare_features! (
651653
// -------------------------------------------------------------------------
652654
);
653655

656+
impl Features {
657+
pub fn dump_feature_usage_metrics(
658+
&self,
659+
metrics_path: PathBuf,
660+
) -> Result<(), Box<dyn std::error::Error>> {
661+
#[derive(serde::Serialize)]
662+
struct LibFeature {
663+
symbol: String,
664+
}
665+
666+
#[derive(serde::Serialize)]
667+
struct LangFeature {
668+
symbol: String,
669+
since: Option<String>,
670+
}
671+
672+
#[derive(serde::Serialize)]
673+
struct FeatureUsage {
674+
lib_features: Vec<LibFeature>,
675+
lang_features: Vec<LangFeature>,
676+
}
677+
678+
let metrics_file = std::fs::File::create(metrics_path)?;
679+
let metrics_file = std::io::BufWriter::new(metrics_file);
680+
681+
let lib_features = self
682+
.enabled_lib_features
683+
.iter()
684+
.map(|EnabledLibFeature { gate_name, .. }| LibFeature { symbol: gate_name.to_string() })
685+
.collect();
686+
687+
let lang_features = self
688+
.enabled_lang_features
689+
.iter()
690+
.map(|EnabledLangFeature { gate_name, stable_since, .. }| LangFeature {
691+
symbol: gate_name.to_string(),
692+
since: stable_since.map(|since| since.to_string()),
693+
})
694+
.collect();
695+
696+
let feature_usage = FeatureUsage { lib_features, lang_features };
697+
698+
serde_json::to_writer(metrics_file, &feature_usage)?;
699+
700+
Ok(())
701+
}
702+
}
703+
654704
/// Some features are not allowed to be used together at the same time, if
655705
/// the two are present, produce an error.
656706
///

Diff for: compiler/rustc_hir_typeck/src/method/suggest.rs

+8-47
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_span::symbol::{Ident, kw, sym};
3131
use rustc_span::{
3232
DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span, Symbol, edit_distance,
3333
};
34+
use rustc_trait_selection::error_reporting::traits::DefIdOrName;
3435
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedNote;
3536
use rustc_trait_selection::infer::InferCtxtExt;
3637
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -45,50 +46,6 @@ use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
4546
use crate::{Expectation, FnCtxt};
4647

4748
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48-
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
49-
let tcx = self.tcx;
50-
match ty.kind() {
51-
// Not all of these (e.g., unsafe fns) implement `FnOnce`,
52-
// so we look for these beforehand.
53-
// FIXME(async_closures): These don't impl `FnOnce` by default.
54-
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(..) => true,
55-
// If it's not a simple function, look for things which implement `FnOnce`.
56-
_ => {
57-
let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
58-
return false;
59-
};
60-
61-
// This conditional prevents us from asking to call errors and unresolved types.
62-
// It might seem that we can use `predicate_must_hold_modulo_regions`,
63-
// but since a Dummy binder is used to fill in the FnOnce trait's arguments,
64-
// type resolution always gives a "maybe" here.
65-
if self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
66-
info!("check deref {:?} error", ty);
67-
matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
68-
}) {
69-
return false;
70-
}
71-
72-
self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
73-
info!("check deref {:?} impl FnOnce", ty);
74-
self.probe(|_| {
75-
let trait_ref =
76-
ty::TraitRef::new(tcx, fn_once, [ty, self.next_ty_var(span)]);
77-
let poly_trait_ref = ty::Binder::dummy(trait_ref);
78-
let obligation = Obligation::misc(
79-
tcx,
80-
span,
81-
self.body_id,
82-
self.param_env,
83-
poly_trait_ref,
84-
);
85-
self.predicate_may_hold(&obligation)
86-
})
87-
})
88-
}
89-
}
90-
}
91-
9249
fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
9350
self.autoderef(span, ty)
9451
.silence_errors()
@@ -2367,12 +2324,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23672324
let is_accessible = field.vis.is_accessible_from(scope, tcx);
23682325

23692326
if is_accessible {
2370-
if self.is_fn_ty(field_ty, span) {
2327+
if let Some((what, _, _)) = self.extract_callable_info(field_ty) {
2328+
let what = match what {
2329+
DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id),
2330+
DefIdOrName::Name(what) => what,
2331+
};
23712332
let expr_span = expr.span.to(item_name.span);
23722333
err.multipart_suggestion(
23732334
format!(
2374-
"to call the function stored in `{item_name}`, \
2375-
surround the field access with parentheses",
2335+
"to call the {what} stored in `{item_name}`, \
2336+
surround the field access with parentheses",
23762337
),
23772338
vec![
23782339
(expr_span.shrink_to_lo(), '('.to_string()),

Diff for: compiler/rustc_mir_build/src/check_unsafety.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,45 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
537537
self.requires_unsafe(expr.span, DerefOfRawPointer);
538538
}
539539
}
540-
ExprKind::InlineAsm { .. } => {
540+
ExprKind::InlineAsm(box InlineAsmExpr {
541+
asm_macro: _,
542+
ref operands,
543+
template: _,
544+
options: _,
545+
line_spans: _,
546+
}) => {
541547
self.requires_unsafe(expr.span, UseOfInlineAssembly);
548+
549+
// For inline asm, do not use `walk_expr`, since we want to handle the label block
550+
// specially.
551+
for op in &**operands {
552+
use rustc_middle::thir::InlineAsmOperand::*;
553+
match op {
554+
In { expr, reg: _ }
555+
| Out { expr: Some(expr), reg: _, late: _ }
556+
| InOut { expr, reg: _, late: _ } => self.visit_expr(&self.thir()[*expr]),
557+
SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
558+
self.visit_expr(&self.thir()[*in_expr]);
559+
if let Some(out_expr) = out_expr {
560+
self.visit_expr(&self.thir()[*out_expr]);
561+
}
562+
}
563+
Out { expr: None, reg: _, late: _ }
564+
| Const { value: _, span: _ }
565+
| SymFn { value: _, span: _ }
566+
| SymStatic { def_id: _ } => {}
567+
Label { block } => {
568+
// Label blocks are safe context.
569+
// `asm!()` is forced to be wrapped inside unsafe. If there's no special
570+
// treatment, the label blocks would also always be unsafe with no way
571+
// of opting out.
572+
self.in_safety_context(SafetyContext::Safe, |this| {
573+
visit::walk_block(this, &this.thir()[*block])
574+
});
575+
}
576+
}
577+
}
578+
return;
542579
}
543580
ExprKind::Adt(box AdtExpr {
544581
adt_def,

Diff for: compiler/rustc_session/src/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ impl OutputFilenames {
10691069
self.with_directory_and_extension(&self.out_directory, extension)
10701070
}
10711071

1072-
fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
1072+
pub fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
10731073
let mut path = directory.join(&self.filestem);
10741074
path.set_extension(extension);
10751075
path

Diff for: compiler/rustc_session/src/options.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,7 @@ options! {
18871887
meta_stats: bool = (false, parse_bool, [UNTRACKED],
18881888
"gather metadata statistics (default: no)"),
18891889
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
1890-
"stores metrics about the errors being emitted by rustc to disk"),
1890+
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
18911891
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
18921892
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
18931893
(default: no)"),

Diff for: compiler/rustc_target/src/callconv/s390x.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
2-
// for a pre-z13 machine or using -mno-vx.
1+
// Reference: ELF Application Binary Interface s390x Supplement
2+
// https://github.com/IBM/s390x-abi
33

4-
use crate::abi::call::{ArgAbi, FnAbi, Reg};
5-
use crate::abi::{HasDataLayout, TyAbiInterface};
4+
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
5+
use crate::abi::{BackendRepr, HasDataLayout, TyAbiInterface};
66
use crate::spec::HasTargetSpec;
77

88
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
9-
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
9+
let size = ret.layout.size;
10+
if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) {
11+
return;
12+
}
13+
if !ret.layout.is_aggregate() && size.bits() <= 64 {
1014
ret.extend_integer_width_to(64);
1115
} else {
1216
ret.make_indirect();
@@ -32,19 +36,25 @@ where
3236
}
3337
return;
3438
}
35-
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
39+
40+
let size = arg.layout.size;
41+
if size.bits() <= 128 && arg.layout.is_single_vector_element(cx, size) {
42+
arg.cast_to(Reg { kind: RegKind::Vector, size });
43+
return;
44+
}
45+
if !arg.layout.is_aggregate() && size.bits() <= 64 {
3646
arg.extend_integer_width_to(64);
3747
return;
3848
}
3949

4050
if arg.layout.is_single_fp_element(cx) {
41-
match arg.layout.size.bytes() {
51+
match size.bytes() {
4252
4 => arg.cast_to(Reg::f32()),
4353
8 => arg.cast_to(Reg::f64()),
4454
_ => arg.make_indirect(),
4555
}
4656
} else {
47-
match arg.layout.size.bytes() {
57+
match size.bytes() {
4858
1 => arg.cast_to(Reg::i8()),
4959
2 => arg.cast_to(Reg::i16()),
5060
4 => arg.cast_to(Reg::i32()),

Diff for: compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
66
base.endian = Endian::Big;
77
// z10 is the oldest CPU supported by LLVM
88
base.cpu = "z10".into();
9-
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
10-
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
11-
base.features = "-vector".into();
129
base.max_atomic_width = Some(128);
1310
base.min_global_align = Some(16);
1411
base.stack_probes = StackProbeType::Inline;

Diff for: compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
66
base.endian = Endian::Big;
77
// z10 is the oldest CPU supported by LLVM
88
base.cpu = "z10".into();
9-
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
10-
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
11-
base.features = "-vector".into();
129
base.max_atomic_width = Some(128);
1310
base.min_global_align = Some(16);
1411
base.static_position_independent_executables = true;

0 commit comments

Comments
 (0)