Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ impl CodegenBackend for CraneliftCodegenBackend {
println!("Cranelift version: {}", cranelift_codegen::VERSION);
}

fn has_mnemonic(&self, sess: &Session, mnemonic: &str) -> bool {
// All Cranelift supported targets support ret except for s390x
mnemonic == "ret" && sess.target.arch != Arch::S390x
}

fn target_cpu(&self, sess: &Session) -> String {
// FIXME handle `-Ctarget-cpu=native`
match sess.opts.cg.target_cpu {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ impl CodegenBackend for LlvmCodegenBackend {
llvm::LLVMRustLLVMHasZstdCompression()
}

fn has_mnemonic(&self, sess: &Session, mnemonic: &str) -> bool {
llvm_util::target_has_mnemonic(sess, mnemonic)
}

fn target_config(&self, sess: &Session) -> TargetConfig {
target_config(sess)
}
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,6 @@ pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
match req.kind {
PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
PrintKind::BackendHasMnemonic => {
let mnemonic = req.arg.as_deref().expect("BackendHasMnemonic requires arg");
print_target_has_mnemonic(tm.raw(), mnemonic, out)
}
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
}
}
Expand Down Expand Up @@ -746,9 +742,9 @@ pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> {
Some(handle_native(name))
}

fn print_target_has_mnemonic(tm: &llvm::TargetMachine, mnemonic: &str, out: &mut String) {
use std::fmt::Write;
pub(crate) fn target_has_mnemonic(sess: &Session, mnemonic: &str) -> bool {
require_inited();
let tm = create_informational_target_machine(sess, false);
let cstr = SmallCStr::new(mnemonic);
let has_mnemonic = unsafe { llvm::LLVMRustTargetHasMnemonic(tm, cstr.as_ptr()) };
writeln!(out, "{}", has_mnemonic).unwrap();
unsafe { llvm::LLVMRustTargetHasMnemonic(tm.raw(), cstr.as_ptr()) }
}
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ pub trait CodegenBackend {
false
}

/// Value printed by `--print=backend-has-mnemonic:...`.
///
/// Used by compiletest to determine whether tests involving `asm!()` should
/// be executed or skipped.
fn has_mnemonic(&self, _sess: &Session, _mnemonic: &str) -> bool {
false
}

/// The metadata loader used to load rlib and dylib metadata.
///
/// Alternative codegen backends may want to use different rlib or dylib formats than the
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,9 @@ fn print_crate_info(
println_info!("{}", calling_conventions.join("\n"));
}
BackendHasMnemonic => {
codegen_backend.print(req, &mut crate_info, sess);
let has_mnemonic: bool =
codegen_backend.has_mnemonic(sess, req.arg.as_ref().unwrap());
println_info!("{has_mnemonic}");
}
BackendHasZstd => {
let has_zstd: bool = codegen_backend.has_zstd();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/hir/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,8 +980,8 @@ impl<'tcx> TyCtxt<'tcx> {
span,
..
}) => {
// Ensure that the returned span has the item's SyntaxContext.
fn_decl_span.find_ancestor_inside(*span).unwrap_or(*span)
// Ensure that the returned span has the closure expression's SyntaxContext.
fn_decl_span.find_ancestor_inside_same_ctxt(*span).unwrap_or(*span)
}
_ => self.hir_span_with_body(hir_id),
};
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,13 +363,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
| UpvarRef { .. }
| VarRef { .. }
| ZstLiteral { .. }
| Yield { .. } => true,
ExprKind::Reborrow { .. } => {
// FIXME(reborrow): matching on a Reborrow expression should be impossible
// currently. Whether this remains to be true, and if the reborrow result then is a
// known valid scrutinee requires further thought.
unreachable!("Reborrow expression in match")
}
| Yield { .. }
| Reborrow { .. } => true,
}
}

Expand Down
58 changes: 36 additions & 22 deletions library/std/tests/sync/mpmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,34 +419,48 @@ fn oneshot_multi_thread_send_recv_stress() {

#[test]
fn stream_send_recv_stress() {
for _ in 0..stress_factor() {
let (tx, rx) = channel();

send(tx, 0);
recv(rx, 0);
thread::scope(|s| {
for _ in 0..stress_factor() {
let (tx, rx) = channel();

send(tx, 0, s);
recv(rx, 0, s);

fn send<'scope, 'env>(
tx: Sender<Box<i32>>,
i: i32,
s: &'scope thread::Scope<'scope, 'env>,
) where
'env: 'scope,
{
if i == 10 {
return;
}

fn send(tx: Sender<Box<i32>>, i: i32) {
if i == 10 {
return;
s.spawn(move || {
tx.send(Box::new(i)).unwrap();
send(tx, i + 1, s);
});
}

thread::spawn(move || {
tx.send(Box::new(i)).unwrap();
send(tx, i + 1);
});
}
fn recv<'scope, 'env>(
rx: Receiver<Box<i32>>,
i: i32,
s: &'scope thread::Scope<'scope, 'env>,
) where
'env: 'scope,
{
if i == 10 {
return;
}

fn recv(rx: Receiver<Box<i32>>, i: i32) {
if i == 10 {
return;
s.spawn(move || {
assert!(*rx.recv().unwrap() == i);
recv(rx, i + 1, s);
});
}

thread::spawn(move || {
assert!(*rx.recv().unwrap() == i);
recv(rx, i + 1);
});
}
}
})
}

#[test]
Expand Down
58 changes: 36 additions & 22 deletions library/std/tests/sync/mpsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,34 +382,48 @@ fn oneshot_multi_thread_send_recv_stress() {

#[test]
fn stream_send_recv_stress() {
for _ in 0..stress_factor() {
let (tx, rx) = channel();

send(tx, 0);
recv(rx, 0);
thread::scope(|s| {
for _ in 0..stress_factor() {
let (tx, rx) = channel();

send(tx, 0, s);
recv(rx, 0, s);

fn send<'scope, 'env>(
tx: Sender<Box<i32>>,
i: i32,
s: &'scope thread::Scope<'scope, 'env>,
) where
'env: 'scope,
{
if i == 10 {
return;
}

fn send(tx: Sender<Box<i32>>, i: i32) {
if i == 10 {
return;
s.spawn(move || {
tx.send(Box::new(i)).unwrap();
send(tx, i + 1, s);
});
}

thread::spawn(move || {
tx.send(Box::new(i)).unwrap();
send(tx, i + 1);
});
}
fn recv<'scope, 'env>(
rx: Receiver<Box<i32>>,
i: i32,
s: &'scope thread::Scope<'scope, 'env>,
) where
'env: 'scope,
{
if i == 10 {
return;
}

fn recv(rx: Receiver<Box<i32>>, i: i32) {
if i == 10 {
return;
s.spawn(move || {
assert!(*rx.recv().unwrap() == i);
recv(rx, i + 1, s);
});
}

thread::spawn(move || {
assert!(*rx.recv().unwrap() == i);
recv(rx, i + 1);
});
}
}
})
}

#[test]
Expand Down
108 changes: 68 additions & 40 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_session::{EarlyDiagCtxt, getopts};
use rustc_span::edition::Edition;
use rustc_span::{FileName, RemapPathScopeComponents};
use rustc_target::spec::TargetTuple;
use smallvec::SmallVec;

use crate::core::new_dcx;
use crate::externalfiles::ExternalHtml;
Expand Down Expand Up @@ -293,7 +294,7 @@ pub(crate) struct RenderOptions {
/// Note: this field is duplicated in `Options` because it's useful to have
/// it in both places.
pub(crate) unstable_features: rustc_feature::UnstableFeatures,
pub(crate) emit: Vec<EmitType>,
pub(crate) emit: SmallVec<[EmitType; 2]>,
/// If `true`, HTML source pages will generate links for items to their definition.
pub(crate) generate_link_to_definition: bool,
/// Set of function-call locations to include as examples
Expand Down Expand Up @@ -327,9 +328,22 @@ pub(crate) enum ModuleSorting {
pub(crate) enum EmitType {
HtmlStaticFiles,
HtmlNonStaticFiles,
// not explicitly nameable by the user for now
JsonFiles,
DepInfo(Option<OutFileName>),
}

impl fmt::Display for EmitType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::HtmlStaticFiles => "html-static-files",
Self::HtmlNonStaticFiles => "html-non-static-files",
Self::JsonFiles => "json-files",
Self::DepInfo(_) => "dep-info",
})
}
}

impl FromStr for EmitType {
type Err = ();

Expand All @@ -352,17 +366,11 @@ impl FromStr for EmitType {
}

impl RenderOptions {
pub(crate) fn should_emit_crate(&self) -> bool {
self.emit.is_empty() || self.emit.contains(&EmitType::HtmlNonStaticFiles)
}

pub(crate) fn dep_info(&self) -> Option<Option<&OutFileName>> {
for emit in &self.emit {
if let EmitType::DepInfo(file) = emit {
return Some(file.as_ref());
}
}
None
self.emit.iter().find_map(|emit| match emit {
EmitType::DepInfo(file) => Some(file.as_ref()),
_ => None,
})
}
}

Expand Down Expand Up @@ -469,26 +477,6 @@ impl Options {

let should_test = matches.opt_present("test");

let mut emit = FxIndexMap::<_, EmitType>::default();
for list in matches.opt_strs("emit") {
if should_test {
dcx.fatal("the `--test` flag and the `--emit` flag are not supported together");
}
for kind in list.split(',') {
match kind.parse() {
Ok(kind) => {
// De-duplicate emit types and the last wins.
// Only one instance for each type is allowed
// regardless the actual data it carries.
// This matches rustc's `--emit` behavior.
emit.insert(std::mem::discriminant(&kind), kind);
}
Err(()) => dcx.fatal(format!("unrecognized emission type: {kind}")),
}
}
}
let emit = emit.into_values().collect::<Vec<_>>();

let show_coverage = matches.opt_present("show-coverage");
let output_format_s = matches.opt_str("output-format");
let output_format = match output_format_s {
Expand Down Expand Up @@ -527,15 +515,55 @@ impl Options {
}
}

if output_format == OutputFormat::Json {
if let Some(emit_flag) = emit.iter().find_map(|emit| match emit {
EmitType::HtmlStaticFiles => Some("html-static-files"),
EmitType::HtmlNonStaticFiles => Some("html-non-static-files"),
EmitType::DepInfo(_) => None,
}) {
dcx.fatal(format!(
"the `--emit={emit_flag}` flag is not supported with `--output-format=json`",
));
let mut emit = FxIndexMap::default();
for list in matches.opt_strs("emit") {
if should_test {
dcx.fatal("the `--test` flag and the `--emit` flag are not supported together");
}
if let OutputFormat::Doctest = output_format {
dcx.fatal("the `--emit` flag is not supported with `--output-format=doctest`");
}

for typ in list.split(',') {
let Ok(typ) = typ.parse::<EmitType>() else {
dcx.fatal(format!("unrecognized emission type: {typ}"))
};

match typ {
EmitType::DepInfo(_) => match output_format {
OutputFormat::Json | OutputFormat::Html => {}
OutputFormat::Doctest => unreachable!(),
},
EmitType::HtmlStaticFiles | EmitType::HtmlNonStaticFiles => match output_format
{
OutputFormat::Html => {}
OutputFormat::Json => dcx.fatal(format!(
"the `--emit={typ}` flag is not supported with `--output-format=json`",
)),
OutputFormat::Doctest => unreachable!(),
},
EmitType::JsonFiles => unreachable!(),
}

// De-duplicate emit types and the last wins.
// Only one instance for each type is allowed
// regardless the actual data it carries.
// This matches rustc's `--emit` behavior.
emit.insert(std::mem::discriminant(&typ), typ);
}
}
let mut emit: SmallVec<[_; 2]> = emit.into_values().collect();
// If `--emit` is absent we'll register default emission types depending on the requested
// output format. We can safely use `is_empty` for this since `--emit=` ("truly empty")
// will have already been rejected above.
if emit.is_empty() {
match output_format {
OutputFormat::Json => emit.push(EmitType::JsonFiles),
OutputFormat::Html => {
emit.push(EmitType::HtmlStaticFiles);
emit.push(EmitType::HtmlNonStaticFiles);
}
OutputFormat::Doctest => {}
}
}

Expand Down
Loading
Loading