Auto merge of #87413 - JohnTitor:rollup-dht22jk, r=JohnTitor
Rollup of 14 pull requests Successful merges: - #86410 (VecMap::get_value_matching should return just one element) - #86790 (Document iteration order of `retain` functions) - #87171 (Remove Option from BufWriter) - #87175 (Stabilize `into_parts()` and `into_error()`) - #87185 (Fix panics on Windows when the build was cancelled) - #87191 (Package LLVM libs for the target rather than the build host) - #87255 (better support for running libcore tests with Miri) - #87266 (Add testcase for 87076) - #87283 (Add `--codegen-backends=foo,bar` configure flag) - #87322 (fix: clarify suggestion that `&T` must refer to `T: Sync` for `&T: Send`) - #87358 (Fix `--dry-run` when download-ci-llvm is set) - #87380 (Don't default to `submodules = true` unless the rust repo has a .git directory) - #87398 (Add test for fonts used for module items) - #87412 (Add missing article) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
67b03007cf
54 changed files with 213 additions and 44 deletions
|
@ -1,4 +1,5 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::fmt::Debug;
|
||||
use std::iter::FromIterator;
|
||||
use std::slice::Iter;
|
||||
use std::vec::IntoIter;
|
||||
|
@ -12,7 +13,8 @@ pub struct VecMap<K, V>(Vec<(K, V)>);
|
|||
|
||||
impl<K, V> VecMap<K, V>
|
||||
where
|
||||
K: PartialEq,
|
||||
K: Debug + PartialEq,
|
||||
V: Debug,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
VecMap(Default::default())
|
||||
|
@ -37,14 +39,31 @@ where
|
|||
self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1)
|
||||
}
|
||||
|
||||
/// Returns the value corresponding to the supplied predicate filter.
|
||||
/// Returns the any value corresponding to the supplied predicate filter.
|
||||
///
|
||||
/// The supplied predicate will be applied to each (key, value) pair and it will return a
|
||||
/// reference to the values where the predicate returns `true`.
|
||||
pub fn get_by(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
|
||||
pub fn any_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
|
||||
self.0.iter().find(|kv| predicate(kv)).map(|elem| &elem.1)
|
||||
}
|
||||
|
||||
/// Returns the value corresponding to the supplied predicate filter. It crashes if there's
|
||||
/// more than one matching element.
|
||||
///
|
||||
/// The supplied predicate will be applied to each (key, value) pair and it will return a
|
||||
/// reference to the value where the predicate returns `true`.
|
||||
pub fn get_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
|
||||
let mut filter = self.0.iter().filter(|kv| predicate(kv));
|
||||
let (_, value) = filter.next()?;
|
||||
// This should return just one element, otherwise it's a bug
|
||||
assert!(
|
||||
filter.next().is_none(),
|
||||
"Collection {:?} should have just one matching element",
|
||||
self
|
||||
);
|
||||
Some(value)
|
||||
}
|
||||
|
||||
/// Returns `true` if the map contains a value for the specified key.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type,
|
||||
|
@ -131,7 +150,7 @@ impl<K, V> IntoIterator for VecMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq, V> Extend<(K, V)> for VecMap<K, V> {
|
||||
impl<K: PartialEq + Debug, V: Debug> Extend<(K, V)> for VecMap<K, V> {
|
||||
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
|
||||
for (k, v) in iter {
|
||||
self.insert(k, v);
|
||||
|
|
|
@ -1857,12 +1857,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
|
||||
// `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync`
|
||||
let refers_to_non_sync = match target_ty.kind() {
|
||||
ty::Ref(_, ref_ty, _) => match self.evaluate_obligation(&obligation) {
|
||||
Ok(eval) if !eval.may_apply() => Some(ref_ty),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let (span_label, span_note) = match refers_to_non_sync {
|
||||
// if `target_ty` is `&T` and `T` fails to impl `Sync`,
|
||||
// include suggestions to make `T: Sync` so that `&T: Send`
|
||||
Some(ref_ty) => (
|
||||
format!(
|
||||
"has type `{}` which {}, because `{}` is not `Sync`",
|
||||
target_ty, trait_explanation, ref_ty
|
||||
),
|
||||
format!(
|
||||
"captured value {} because `&` references cannot be sent unless their referent is `Sync`",
|
||||
trait_explanation
|
||||
),
|
||||
),
|
||||
None => (
|
||||
format!("has type `{}` which {}", target_ty, trait_explanation),
|
||||
format!("captured value {}", trait_explanation),
|
||||
),
|
||||
};
|
||||
|
||||
let mut span = MultiSpan::from_span(upvar_span);
|
||||
span.push_span_label(
|
||||
upvar_span,
|
||||
format!("has type `{}` which {}", target_ty, trait_explanation),
|
||||
);
|
||||
err.span_note(span, &format!("captured value {}", trait_explanation));
|
||||
span.push_span_label(upvar_span, span_label);
|
||||
err.span_note(span, &span_note);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -364,7 +364,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
let concrete_ty = tcx
|
||||
.mir_borrowck(owner.expect_local())
|
||||
.concrete_opaque_types
|
||||
.get_by(|(key, _)| key.def_id == def_id.to_def_id())
|
||||
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
||||
.map(|concrete_ty| *concrete_ty)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.delay_span_bug(
|
||||
|
@ -512,8 +512,15 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
|||
|
||||
struct ConstraintLocator<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// def_id of the opaque type whose defining uses are being checked
|
||||
def_id: DefId,
|
||||
// (first found type span, actual type)
|
||||
|
||||
/// as we walk the defining uses, we are checking that all of them
|
||||
/// define the same hidden type. This variable is set to `Some`
|
||||
/// with the first type that we find, and then later types are
|
||||
/// checked against it (we also carry the span of that first
|
||||
/// type).
|
||||
found: Option<(Span, Ty<'tcx>)>,
|
||||
}
|
||||
|
||||
|
@ -531,7 +538,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
|
|||
.tcx
|
||||
.typeck(def_id)
|
||||
.concrete_opaque_types
|
||||
.get_by(|(key, _)| key.def_id == self.def_id)
|
||||
.any_value_matching(|(key, _)| key.def_id == self.def_id)
|
||||
.is_none()
|
||||
{
|
||||
debug!("no constraints in typeck results");
|
||||
|
|
|
@ -38,7 +38,7 @@ changelog-seen = 2
|
|||
# This is false by default so that distributions don't unexpectedly download
|
||||
# LLVM from the internet.
|
||||
#
|
||||
# All tier 1 targets are currently supported; set this to `"if-supported"` if
|
||||
# All tier 1 targets are currently supported; set this to `"if-available"` if
|
||||
# you are not sure whether you're on a tier 1 target.
|
||||
#
|
||||
# We also currently only support this when building LLVM for the build triple.
|
||||
|
|
|
@ -935,6 +935,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
|
||||
/// The elements are visited in ascending key order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -846,6 +846,7 @@ impl<T> BTreeSet<T> {
|
|||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
|
||||
/// The elements are visited in ascending order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
//! [`Rc`]: rc
|
||||
//! [`RefCell`]: core::cell
|
||||
|
||||
// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
|
||||
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
|
||||
// rustc itself never sets the feature, so this line has no affect there.
|
||||
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
|
||||
#![allow(unused_attributes)]
|
||||
#![stable(feature = "alloc", since = "1.36.0")]
|
||||
#![doc(
|
||||
|
|
|
@ -49,6 +49,10 @@
|
|||
//
|
||||
// This cfg won't affect doc tests.
|
||||
#![cfg(not(test))]
|
||||
// To run libcore tests without x.py without ending up with two copies of libcore, Miri needs to be
|
||||
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
|
||||
// rustc itself never sets the feature, so this line has no affect there.
|
||||
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
|
||||
#![stable(feature = "core", since = "1.6.0")]
|
||||
#![doc(
|
||||
html_playground_url = "https://play.rust-lang.org/",
|
||||
|
|
|
@ -934,6 +934,7 @@ where
|
|||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
|
||||
/// The elements are visited in unsorted (and unspecified) order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -912,6 +912,7 @@ where
|
|||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
|
||||
/// The elements are visited in unsorted (and unspecified) order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -68,7 +68,7 @@ use crate::ptr;
|
|||
/// [`flush`]: BufWriter::flush
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct BufWriter<W: Write> {
|
||||
inner: Option<W>,
|
||||
inner: W,
|
||||
// The buffer. Avoid using this like a normal `Vec` in common code paths.
|
||||
// That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
|
||||
// methods that require bounds checking or the like. This makes an enormous
|
||||
|
@ -112,7 +112,7 @@ impl<W: Write> BufWriter<W> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
|
||||
BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false }
|
||||
BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
|
||||
}
|
||||
|
||||
/// Send data in our local buffer into the inner writer, looping as
|
||||
|
@ -161,10 +161,9 @@ impl<W: Write> BufWriter<W> {
|
|||
}
|
||||
|
||||
let mut guard = BufGuard::new(&mut self.buf);
|
||||
let inner = self.inner.as_mut().unwrap();
|
||||
while !guard.done() {
|
||||
self.panicked = true;
|
||||
let r = inner.write(guard.remaining());
|
||||
let r = self.inner.write(guard.remaining());
|
||||
self.panicked = false;
|
||||
|
||||
match r {
|
||||
|
@ -212,7 +211,7 @@ impl<W: Write> BufWriter<W> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn get_ref(&self) -> &W {
|
||||
self.inner.as_ref().unwrap()
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying writer.
|
||||
|
@ -232,7 +231,7 @@ impl<W: Write> BufWriter<W> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn get_mut(&mut self) -> &mut W {
|
||||
self.inner.as_mut().unwrap()
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Returns a reference to the internally buffered data.
|
||||
|
@ -308,7 +307,7 @@ impl<W: Write> BufWriter<W> {
|
|||
pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
|
||||
match self.flush_buf() {
|
||||
Err(e) => Err(IntoInnerError::new(self, e)),
|
||||
Ok(()) => Ok(self.inner.take().unwrap()),
|
||||
Ok(()) => Ok(self.into_raw_parts().0),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,7 +338,12 @@ impl<W: Write> BufWriter<W> {
|
|||
pub fn into_raw_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
|
||||
let buf = mem::take(&mut self.buf);
|
||||
let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
|
||||
(self.inner.take().unwrap(), buf)
|
||||
|
||||
// SAFETY: forget(self) prevents double dropping inner
|
||||
let inner = unsafe { ptr::read(&mut self.inner) };
|
||||
mem::forget(self);
|
||||
|
||||
(inner, buf)
|
||||
}
|
||||
|
||||
// Ensure this function does not get inlined into `write`, so that it
|
||||
|
@ -643,7 +647,7 @@ where
|
|||
{
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt.debug_struct("BufWriter")
|
||||
.field("writer", &self.inner.as_ref().unwrap())
|
||||
.field("writer", &self.inner)
|
||||
.field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
|
||||
.finish()
|
||||
}
|
||||
|
@ -663,7 +667,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<W: Write> Drop for BufWriter<W> {
|
||||
fn drop(&mut self) {
|
||||
if self.inner.is_some() && !self.panicked {
|
||||
if !self.panicked {
|
||||
// dtors should not panic, so we ignore a failed flush
|
||||
let _r = self.flush_buf();
|
||||
}
|
||||
|
|
|
@ -133,7 +133,6 @@ impl<W> IntoInnerError<W> {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #![feature(io_into_inner_error_parts)]
|
||||
/// use std::io::{BufWriter, ErrorKind, Write};
|
||||
///
|
||||
/// let mut not_enough_space = [0u8; 10];
|
||||
|
@ -143,7 +142,7 @@ impl<W> IntoInnerError<W> {
|
|||
/// let err = into_inner_err.into_error();
|
||||
/// assert_eq!(err.kind(), ErrorKind::WriteZero);
|
||||
/// ```
|
||||
#[unstable(feature = "io_into_inner_error_parts", issue = "79704")]
|
||||
#[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
|
||||
pub fn into_error(self) -> Error {
|
||||
self.1
|
||||
}
|
||||
|
@ -156,7 +155,6 @@ impl<W> IntoInnerError<W> {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #![feature(io_into_inner_error_parts)]
|
||||
/// use std::io::{BufWriter, ErrorKind, Write};
|
||||
///
|
||||
/// let mut not_enough_space = [0u8; 10];
|
||||
|
@ -167,7 +165,7 @@ impl<W> IntoInnerError<W> {
|
|||
/// assert_eq!(err.kind(), ErrorKind::WriteZero);
|
||||
/// assert_eq!(recovered_writer.buffer(), b"t be actually written");
|
||||
/// ```
|
||||
#[unstable(feature = "io_into_inner_error_parts", issue = "79704")]
|
||||
#[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
|
||||
pub fn into_parts(self) -> (Error, W) {
|
||||
(self.1, self.0)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//!
|
||||
//! This module contains some of the real meat in the rustbuild build system
|
||||
//! which is where Cargo is used to compile the standard library, libtest, and
|
||||
//! compiler. This module is also responsible for assembling the sysroot as it
|
||||
//! the compiler. This module is also responsible for assembling the sysroot as it
|
||||
//! goes along from the output of the previous stage.
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
|
|
@ -13,6 +13,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::str::FromStr;
|
||||
|
||||
use crate::cache::{Interned, INTERNER};
|
||||
use crate::channel::GitInfo;
|
||||
pub use crate::flags::Subcommand;
|
||||
use crate::flags::{Color, Flags};
|
||||
use crate::util::exe;
|
||||
|
@ -48,7 +49,7 @@ pub struct Config {
|
|||
/// Call Build::ninja() instead of this.
|
||||
pub ninja_in_file: bool,
|
||||
pub verbose: usize,
|
||||
pub submodules: bool,
|
||||
pub submodules: Option<bool>,
|
||||
pub fast_submodules: bool,
|
||||
pub compiler_docs: bool,
|
||||
pub docs_minification: bool,
|
||||
|
@ -552,7 +553,7 @@ impl Config {
|
|||
config.backtrace = true;
|
||||
config.rust_optimize = true;
|
||||
config.rust_optimize_tests = true;
|
||||
config.submodules = true;
|
||||
config.submodules = None;
|
||||
config.fast_submodules = true;
|
||||
config.docs = true;
|
||||
config.docs_minification = true;
|
||||
|
@ -658,11 +659,11 @@ impl Config {
|
|||
config.npm = build.npm.map(PathBuf::from);
|
||||
config.gdb = build.gdb.map(PathBuf::from);
|
||||
config.python = build.python.map(PathBuf::from);
|
||||
config.submodules = build.submodules;
|
||||
set(&mut config.low_priority, build.low_priority);
|
||||
set(&mut config.compiler_docs, build.compiler_docs);
|
||||
set(&mut config.docs_minification, build.docs_minification);
|
||||
set(&mut config.docs, build.docs);
|
||||
set(&mut config.submodules, build.submodules);
|
||||
set(&mut config.fast_submodules, build.fast_submodules);
|
||||
set(&mut config.locked_deps, build.locked_deps);
|
||||
set(&mut config.vendor, build.vendor);
|
||||
|
@ -792,8 +793,16 @@ impl Config {
|
|||
|
||||
// CI-built LLVM can be either dynamic or static.
|
||||
let ci_llvm = config.out.join(&*config.build.triple).join("ci-llvm");
|
||||
let link_type = t!(std::fs::read_to_string(ci_llvm.join("link-type.txt")));
|
||||
config.llvm_link_shared = link_type == "dynamic";
|
||||
config.llvm_link_shared = if config.dry_run {
|
||||
// just assume dynamic for now
|
||||
true
|
||||
} else {
|
||||
let link_type = t!(
|
||||
std::fs::read_to_string(ci_llvm.join("link-type.txt")),
|
||||
format!("CI llvm missing: {}", ci_llvm.display())
|
||||
);
|
||||
link_type == "dynamic"
|
||||
};
|
||||
}
|
||||
|
||||
if config.llvm_thin_lto {
|
||||
|
@ -1075,6 +1084,10 @@ impl Config {
|
|||
pub fn llvm_enabled(&self) -> bool {
|
||||
self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
|
||||
}
|
||||
|
||||
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
|
||||
self.submodules.unwrap_or(rust_info.is_git())
|
||||
}
|
||||
}
|
||||
|
||||
fn set<T>(field: &mut T, val: Option<T>) {
|
||||
|
|
|
@ -160,6 +160,7 @@ o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of tw
|
|||
o("extended", "build.extended", "build an extended rust tool set")
|
||||
|
||||
v("tools", None, "List of extended tools will be installed")
|
||||
v("codegen-backends", None, "List of codegen backends to build")
|
||||
v("build", "build.build", "GNUs ./configure syntax LLVM build triple")
|
||||
v("host", None, "GNUs ./configure syntax LLVM host triples")
|
||||
v("target", None, "GNUs ./configure syntax LLVM target triples")
|
||||
|
@ -339,6 +340,8 @@ for key in known_args:
|
|||
set('target.{}.llvm-filecheck'.format(build()), value)
|
||||
elif option.name == 'tools':
|
||||
set('build.tools', value.split(','))
|
||||
elif option.name == 'codegen-backends':
|
||||
set('rust.codegen-backends', value.split(','))
|
||||
elif option.name == 'host':
|
||||
set('build.host', value.split(','))
|
||||
elif option.name == 'target':
|
||||
|
|
|
@ -1955,8 +1955,16 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
|
|||
cmd.arg("--libfiles");
|
||||
builder.verbose(&format!("running {:?}", cmd));
|
||||
let files = output(&mut cmd);
|
||||
let build_llvm_out = &builder.llvm_out(builder.config.build);
|
||||
let target_llvm_out = &builder.llvm_out(target);
|
||||
for file in files.trim_end().split(' ') {
|
||||
builder.install(Path::new(file), dst_libdir, 0o644);
|
||||
// If we're not using a custom LLVM, make sure we package for the target.
|
||||
let file = if let Ok(relative_path) = Path::new(file).strip_prefix(build_llvm_out) {
|
||||
target_llvm_out.join(relative_path)
|
||||
} else {
|
||||
PathBuf::from(file)
|
||||
};
|
||||
builder.install(&file, dst_libdir, 0o644);
|
||||
}
|
||||
!builder.config.dry_run
|
||||
} else {
|
||||
|
|
|
@ -103,12 +103,20 @@ pub unsafe fn setup(build: &mut Build) {
|
|||
};
|
||||
|
||||
let parent = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid.parse().unwrap());
|
||||
assert!(
|
||||
!parent.is_null(),
|
||||
"PID `{}` doesn't seem to exist: {}",
|
||||
pid,
|
||||
io::Error::last_os_error()
|
||||
);
|
||||
|
||||
// If we get a null parent pointer here, it is possible that either
|
||||
// we have got an invalid pid or the parent process has been closed.
|
||||
// Since the first case rarely happens
|
||||
// (only when wrongly setting the environmental variable),
|
||||
// so it might be better to improve the experience of the second case
|
||||
// when users have interrupted the parent process and we don't finish
|
||||
// duplicating the handle yet.
|
||||
// We just need close the job object if that occurs.
|
||||
if parent.is_null() {
|
||||
CloseHandle(job);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut parent_handle = ptr::null_mut();
|
||||
let r = DuplicateHandle(
|
||||
GetCurrentProcess(),
|
||||
|
|
|
@ -486,7 +486,7 @@ impl Build {
|
|||
t!(std::fs::read_dir(dir)).next().is_none()
|
||||
}
|
||||
|
||||
if !self.config.submodules {
|
||||
if !self.config.submodules(&self.rust_info) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -562,7 +562,7 @@ impl Build {
|
|||
"library/stdarch",
|
||||
];
|
||||
// Avoid running git when there isn't a git checkout.
|
||||
if !self.config.submodules {
|
||||
if !self.config.submodules(&self.rust_info) {
|
||||
return;
|
||||
}
|
||||
let output = output(
|
||||
|
|
4
src/test/rustdoc-gui/module-items-font.goml
Normal file
4
src/test/rustdoc-gui/module-items-font.goml
Normal file
|
@ -0,0 +1,4 @@
|
|||
// This test checks that the correct font is used on module items (in index.html pages).
|
||||
goto: file://|DOC_PATH|/test_docs/index.html
|
||||
assert-css: (".item-table .module-item a", {"font-family": '"Fira Sans", Arial, sans-serif'}, ALL)
|
||||
assert-css: (".item-table .docblock-short", {"font-family": '"Source Serif 4", "Noto Sans KR", serif'}, ALL)
|
25
src/test/ui/async-await/issue-86507.rs
Normal file
25
src/test/ui/async-await/issue-86507.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
// edition:2018
|
||||
|
||||
use ::core::pin::Pin;
|
||||
use ::core::future::Future;
|
||||
use ::core::marker::Send;
|
||||
|
||||
trait Foo {
|
||||
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
|
||||
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
|
||||
where 'me: 'async_trait;
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
|
||||
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
|
||||
where 'me:'async_trait {
|
||||
Box::pin( //~ ERROR future cannot be sent between threads safely
|
||||
async move {
|
||||
let x = x;
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
23
src/test/ui/async-await/issue-86507.stderr
Normal file
23
src/test/ui/async-await/issue-86507.stderr
Normal file
|
@ -0,0 +1,23 @@
|
|||
error: future cannot be sent between threads safely
|
||||
--> $DIR/issue-86507.rs:17:13
|
||||
|
|
||||
LL | / Box::pin(
|
||||
LL | | async move {
|
||||
LL | | let x = x;
|
||||
LL | | }
|
||||
LL | | )
|
||||
| |_____________^ future created by async block is not `Send`
|
||||
|
|
||||
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
|
||||
--> $DIR/issue-86507.rs:19:29
|
||||
|
|
||||
LL | let x = x;
|
||||
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||
= note: required for the cast to the object type `dyn Future<Output = ()> + Send`
|
||||
help: consider further restricting type parameter `T`
|
||||
|
|
||||
LL | where 'me:'async_trait, T: std::marker::Sync {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
20
src/test/ui/const-generics/issues/issue-87076.rs
Normal file
20
src/test/ui/const-generics/issues/issue-87076.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// build-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct UnitDims {
|
||||
pub time: u8,
|
||||
pub length: u8,
|
||||
}
|
||||
|
||||
pub struct UnitValue<const DIMS: UnitDims>;
|
||||
|
||||
impl<const DIMS: UnitDims> UnitValue<DIMS> {
|
||||
fn crash() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
UnitValue::<{ UnitDims { time: 1, length: 2 } }>::crash();
|
||||
}
|
|
@ -55,11 +55,11 @@ note: captured value is not `Send`
|
|||
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
||||
| ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
|
||||
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
|
||||
note: captured value is not `Send`
|
||||
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
|
||||
--> $DIR/future_not_send.rs:20:40
|
||||
|
|
||||
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
||||
| ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`
|
||||
| ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
|
||||
= note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
|
||||
|
||||
error: future cannot be sent between threads safely
|
||||
|
|
Loading…
Add table
Reference in a new issue