Skip to content

Commit

Permalink
Auto merge of rust-lang#133287 - matthiaskrgr:rollup-ab9j3pu, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

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
  • Loading branch information
bors committed Nov 21, 2024
2 parents 717f5df + df2413c commit 75703c1
Show file tree
Hide file tree
Showing 40 changed files with 1,287 additions and 170 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3685,6 +3685,8 @@ version = "0.0.0"
dependencies = [
"rustc_data_structures",
"rustc_span",
"serde",
"serde_json",
]

[[package]]
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,24 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
}
}

pub fn is_single_vector_element<C>(self, cx: &C, expected_size: Size) -> bool
where
Ty: TyAbiInterface<'a, C>,
C: HasDataLayout,
{
match self.backend_repr {
BackendRepr::Vector { .. } => self.size == expected_size,
BackendRepr::Memory { .. } => {
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
self.field(cx, 0).is_single_vector_element(cx, expected_size)
} else {
false
}
}
_ => false,
}
}

pub fn is_adt<C>(self) -> bool
where
Ty: TyAbiInterface<'a, C>,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_driver_impl/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ driver_impl_rlink_rustc_version_mismatch = .rlink file was produced by rustc ver
driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}`
driver_impl_rlink_wrong_file_type = The input does not look like a .rlink file
driver_impl_unstable_feature_usage = cannot dump feature usage metrics: {$error}
24 changes: 23 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use rustc_interface::{Linker, Queries, interface, passes};
use rustc_lint::unerased_lint_store;
use rustc_metadata::creader::MetadataLoader;
use rustc_metadata::locator;
use rustc_middle::ty::TyCtxt;
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_session::config::{
CG_OPTIONS, ErrorOutputType, Input, OutFileName, OutputType, UnstableOptions, Z_OPTIONS,
Expand Down Expand Up @@ -103,7 +104,7 @@ mod signal_handler {

use crate::session_diagnostics::{
RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead,
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage,
};

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

if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
queries.global_ctxt()?.enter(|tcxt| dump_feature_usage_metrics(tcxt, metrics_dir));
}

if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
return early_exit();
}
Expand Down Expand Up @@ -475,6 +480,23 @@ fn run_compiler(
})
}

fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &PathBuf) {
let output_filenames = tcxt.output_filenames(());
let mut metrics_file_name = std::ffi::OsString::from("unstable_feature_usage_metrics-");
let mut metrics_path = output_filenames.with_directory_and_extension(metrics_dir, "json");
let metrics_file_stem =
metrics_path.file_name().expect("there should be a valid default output filename");
metrics_file_name.push(metrics_file_stem);
metrics_path.pop();
metrics_path.push(metrics_file_name);
if let Err(error) = tcxt.features().dump_feature_usage_metrics(metrics_path) {
// FIXME(yaahc): once metrics can be enabled by default we will want "failure to emit
// default metrics" to only produce a warning when metrics are enabled by default and emit
// an error only when the user manually enables metrics
tcxt.dcx().emit_err(UnstableFeatureUsage { error });
}
}

// Extract output directory and file from matches.
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileName>) {
let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_driver_impl/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::error::Error;

use rustc_macros::{Diagnostic, Subdiagnostic};

#[derive(Diagnostic)]
Expand Down Expand Up @@ -93,3 +95,9 @@ pub(crate) struct IceFlags {
#[derive(Diagnostic)]
#[diag(driver_impl_ice_exclude_cargo_defaults)]
pub(crate) struct IceExcludeCargoDefaults;

#[derive(Diagnostic)]
#[diag(driver_impl_unstable_feature_usage)]
pub(crate) struct UnstableFeatureUsage {
pub error: Box<dyn Error>,
}
2 changes: 2 additions & 0 deletions compiler/rustc_feature/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ edition = "2021"
# tidy-alphabetical-start
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_span = { path = "../rustc_span" }
serde = { version = "1.0.125", features = [ "derive" ] }
serde_json = "1.0.59"
# tidy-alphabetical-end
50 changes: 50 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! List of the unstable feature gates.

use std::path::PathBuf;

use rustc_data_structures::fx::FxHashSet;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, sym};
Expand Down Expand Up @@ -651,6 +653,54 @@ declare_features! (
// -------------------------------------------------------------------------
);

impl Features {
pub fn dump_feature_usage_metrics(
&self,
metrics_path: PathBuf,
) -> Result<(), Box<dyn std::error::Error>> {
#[derive(serde::Serialize)]
struct LibFeature {
symbol: String,
}

#[derive(serde::Serialize)]
struct LangFeature {
symbol: String,
since: Option<String>,
}

#[derive(serde::Serialize)]
struct FeatureUsage {
lib_features: Vec<LibFeature>,
lang_features: Vec<LangFeature>,
}

let metrics_file = std::fs::File::create(metrics_path)?;
let metrics_file = std::io::BufWriter::new(metrics_file);

let lib_features = self
.enabled_lib_features
.iter()
.map(|EnabledLibFeature { gate_name, .. }| LibFeature { symbol: gate_name.to_string() })
.collect();

let lang_features = self
.enabled_lang_features
.iter()
.map(|EnabledLangFeature { gate_name, stable_since, .. }| LangFeature {
symbol: gate_name.to_string(),
since: stable_since.map(|since| since.to_string()),
})
.collect();

let feature_usage = FeatureUsage { lib_features, lang_features };

serde_json::to_writer(metrics_file, &feature_usage)?;

Ok(())
}
}

/// Some features are not allowed to be used together at the same time, if
/// the two are present, produce an error.
///
Expand Down
55 changes: 8 additions & 47 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use rustc_span::symbol::{Ident, kw, sym};
use rustc_span::{
DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span, Symbol, edit_distance,
};
use rustc_trait_selection::error_reporting::traits::DefIdOrName;
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedNote;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
Expand All @@ -45,50 +46,6 @@ use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
use crate::{Expectation, FnCtxt};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
let tcx = self.tcx;
match ty.kind() {
// Not all of these (e.g., unsafe fns) implement `FnOnce`,
// so we look for these beforehand.
// FIXME(async_closures): These don't impl `FnOnce` by default.
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(..) => true,
// If it's not a simple function, look for things which implement `FnOnce`.
_ => {
let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
return false;
};

// This conditional prevents us from asking to call errors and unresolved types.
// It might seem that we can use `predicate_must_hold_modulo_regions`,
// but since a Dummy binder is used to fill in the FnOnce trait's arguments,
// type resolution always gives a "maybe" here.
if self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
info!("check deref {:?} error", ty);
matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
}) {
return false;
}

self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
info!("check deref {:?} impl FnOnce", ty);
self.probe(|_| {
let trait_ref =
ty::TraitRef::new(tcx, fn_once, [ty, self.next_ty_var(span)]);
let poly_trait_ref = ty::Binder::dummy(trait_ref);
let obligation = Obligation::misc(
tcx,
span,
self.body_id,
self.param_env,
poly_trait_ref,
);
self.predicate_may_hold(&obligation)
})
})
}
}
}

fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
self.autoderef(span, ty)
.silence_errors()
Expand Down Expand Up @@ -2367,12 +2324,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let is_accessible = field.vis.is_accessible_from(scope, tcx);

if is_accessible {
if self.is_fn_ty(field_ty, span) {
if let Some((what, _, _)) = self.extract_callable_info(field_ty) {
let what = match what {
DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id),
DefIdOrName::Name(what) => what,
};
let expr_span = expr.span.to(item_name.span);
err.multipart_suggestion(
format!(
"to call the function stored in `{item_name}`, \
surround the field access with parentheses",
"to call the {what} stored in `{item_name}`, \
surround the field access with parentheses",
),
vec![
(expr_span.shrink_to_lo(), '('.to_string()),
Expand Down
39 changes: 38 additions & 1 deletion compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,45 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
self.requires_unsafe(expr.span, DerefOfRawPointer);
}
}
ExprKind::InlineAsm { .. } => {
ExprKind::InlineAsm(box InlineAsmExpr {
asm_macro: _,
ref operands,
template: _,
options: _,
line_spans: _,
}) => {
self.requires_unsafe(expr.span, UseOfInlineAssembly);

// For inline asm, do not use `walk_expr`, since we want to handle the label block
// specially.
for op in &**operands {
use rustc_middle::thir::InlineAsmOperand::*;
match op {
In { expr, reg: _ }
| Out { expr: Some(expr), reg: _, late: _ }
| InOut { expr, reg: _, late: _ } => self.visit_expr(&self.thir()[*expr]),
SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
self.visit_expr(&self.thir()[*in_expr]);
if let Some(out_expr) = out_expr {
self.visit_expr(&self.thir()[*out_expr]);
}
}
Out { expr: None, reg: _, late: _ }
| Const { value: _, span: _ }
| SymFn { value: _, span: _ }
| SymStatic { def_id: _ } => {}
Label { block } => {
// Label blocks are safe context.
// `asm!()` is forced to be wrapped inside unsafe. If there's no special
// treatment, the label blocks would also always be unsafe with no way
// of opting out.
self.in_safety_context(SafetyContext::Safe, |this| {
visit::walk_block(this, &this.thir()[*block])
});
}
}
}
return;
}
ExprKind::Adt(box AdtExpr {
adt_def,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ impl OutputFilenames {
self.with_directory_and_extension(&self.out_directory, extension)
}

fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
pub fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
let mut path = directory.join(&self.filestem);
path.set_extension(extension);
path
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1887,7 +1887,7 @@ options! {
meta_stats: bool = (false, parse_bool, [UNTRACKED],
"gather metadata statistics (default: no)"),
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
"stores metrics about the errors being emitted by rustc to disk"),
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),
Expand Down
26 changes: 18 additions & 8 deletions compiler/rustc_target/src/callconv/s390x.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
// for a pre-z13 machine or using -mno-vx.
// Reference: ELF Application Binary Interface s390x Supplement
// https://github.com/IBM/s390x-abi

use crate::abi::call::{ArgAbi, FnAbi, Reg};
use crate::abi::{HasDataLayout, TyAbiInterface};
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
use crate::abi::{BackendRepr, HasDataLayout, TyAbiInterface};
use crate::spec::HasTargetSpec;

fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
let size = ret.layout.size;
if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) {
return;
}
if !ret.layout.is_aggregate() && size.bits() <= 64 {
ret.extend_integer_width_to(64);
} else {
ret.make_indirect();
Expand All @@ -32,19 +36,25 @@ where
}
return;
}
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {

let size = arg.layout.size;
if size.bits() <= 128 && arg.layout.is_single_vector_element(cx, size) {
arg.cast_to(Reg { kind: RegKind::Vector, size });
return;
}
if !arg.layout.is_aggregate() && size.bits() <= 64 {
arg.extend_integer_width_to(64);
return;
}

if arg.layout.is_single_fp_element(cx) {
match arg.layout.size.bytes() {
match size.bytes() {
4 => arg.cast_to(Reg::f32()),
8 => arg.cast_to(Reg::f64()),
_ => arg.make_indirect(),
}
} else {
match arg.layout.size.bytes() {
match size.bytes() {
1 => arg.cast_to(Reg::i8()),
2 => arg.cast_to(Reg::i16()),
4 => arg.cast_to(Reg::i32()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
base.endian = Endian::Big;
// z10 is the oldest CPU supported by LLVM
base.cpu = "z10".into();
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
base.features = "-vector".into();
base.max_atomic_width = Some(128);
base.min_global_align = Some(16);
base.stack_probes = StackProbeType::Inline;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
base.endian = Endian::Big;
// z10 is the oldest CPU supported by LLVM
base.cpu = "z10".into();
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
base.features = "-vector".into();
base.max_atomic_width = Some(128);
base.min_global_align = Some(16);
base.static_position_independent_executables = true;
Expand Down
Loading

0 comments on commit 75703c1

Please sign in to comment.